package com.meidusa.amoeba.heartbeat;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
*
* @author Struct
*
*/
public abstract class HeartbeatDelayed implements Delayed {
private long time;
/** Sequence number to break ties FIFO */
private final long sequenceNumber;
private long nano_origin = System.nanoTime();
private static final AtomicLong sequencer = new AtomicLong(0);
private long nextFireTime = nano_origin;
public boolean isCycle(){
return false;
}
public HeartbeatDelayed(long nsTime, TimeUnit timeUnit){
this.time = TimeUnit.NANOSECONDS.convert(nsTime, timeUnit);
this.sequenceNumber = sequencer.getAndIncrement();
nextFireTime = time + nano_origin;
}
public abstract String getName();
public void setDelayedTime(long time, TimeUnit timeUnit) {
nano_origin = System.nanoTime();
this.time = TimeUnit.NANOSECONDS.convert(time, timeUnit);
nextFireTime = time + nano_origin;
}
/**
* this method will be invoked when cancel from heart beat manager
*/
public void cancel(){
}
public void reset(){
nano_origin = System.nanoTime();
nextFireTime = time + nano_origin;
}
public long getDelay(TimeUnit unit) {
long d = unit.convert(time - now(), TimeUnit.NANOSECONDS);
return d;
}
public abstract Status doCheck();
public int compareTo(Delayed other) {
if (other == this) // compare zero ONLY if same object
return 0;
HeartbeatDelayed x = (HeartbeatDelayed) other;
long diff = nextFireTime - x.nextFireTime;
if (diff < 0) return -1;
else if (diff > 0) return 1;
else if (sequenceNumber < x.sequenceNumber) return -1;
else return 1;
}
/**
* Returns nanosecond time offset by origin
*/
final long now() {
return System.nanoTime() - nano_origin;
}
}