Package com.sissi.server.ha.impl

Source Code of com.sissi.server.ha.impl.PingKeepalive

package com.sissi.server.ha.impl;

import java.util.UUID;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sissi.commons.Trace;
import com.sissi.context.JIDContext;
import com.sissi.protocol.ProtocolType;
import com.sissi.protocol.iq.IQ;
import com.sissi.protocol.iq.ping.Ping;
import com.sissi.resource.ResourceCounter;
import com.sissi.server.ha.Keepalive;
import com.sissi.thread.Runner;
import com.sissi.thread.impl.ExecuteInterval;

/**
* Ping/Pong
*
* @author kim 2014年1月8日
*/
public class PingKeepalive implements Keepalive, Runnable {

  private final Log log = LogFactory.getLog(this.getClass());

  private final String resource = PingTimeout.class.getSimpleName();

  private final DelayQueue<PingTimeout> timeouts = new DelayQueue<PingTimeout>();

  private final long interval;

  private final ResourceCounter resourceCounter;

  public PingKeepalive(Runner runner, ExecuteInterval interval, ResourceCounter resourceCounter) {
    super();
    this.resourceCounter = resourceCounter;
    this.interval = interval.convert(TimeUnit.MILLISECONDS);
    runner.executor(1, this);
  }

  @Override
  public PingKeepalive ping(JIDContext context) {
    String uid = UUID.randomUUID().toString();
    this.timeouts.offer(new PingTimeout(context.ping(uid.hashCode()).write(new IQ().setId(uid).add(Ping.PING).setType(ProtocolType.GET), true)));
    return this;
  }

  @Override
  public void run() {
    while (true) {
      try {
        this.timeouts.take().timeout();
      } catch (Exception e) {
        this.log.warn(e.toString());
        Trace.trace(this.log, e);
      }
    }
  }

  private class PingTimeout implements Delayed {

    private final JIDContext context;

    private final long deadline;

    public PingTimeout(JIDContext context) {
      this.context = context;
      this.deadline = PingKeepalive.this.interval + System.currentTimeMillis();
      PingKeepalive.this.resourceCounter.increment(PingKeepalive.this.resource);
    }

    public PingTimeout timeout() {
      this.context.closeTimeout();
      PingKeepalive.this.resourceCounter.decrement(PingKeepalive.this.resource);
      return this;
    }

    public long getDelay(TimeUnit unit) {
      return unit.convert(this.deadline - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    public int compareTo(Delayed o) {
      return o.getDelay(TimeUnit.MILLISECONDS) >= this.getDelay(TimeUnit.MILLISECONDS) ? 1 : -1;
    }
  }
}
TOP

Related Classes of com.sissi.server.ha.impl.PingKeepalive

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.