package org.threadly.concurrent;
import java.util.concurrent.Callable;
import org.threadly.test.concurrent.TestCondition;
import org.threadly.test.concurrent.TestUtils;
import org.threadly.util.Clock;
@SuppressWarnings("javadoc")
public class TestCallable extends TestCondition
implements Callable<Object> {
private static final int RUN_CONDITION_POLL_INTERVAL = 20;
private final long runDurration;
private final long creationTime;
private final Object result;
private volatile long callTime;
private volatile boolean done;
public TestCallable() {
this(0);
}
public TestCallable(long runDurration) {
this.runDurration = runDurration;
this.creationTime = Clock.accurateForwardProgressingMillis();
callTime = -1;
result = new Object();
done = false;
}
/**
* Call to get the time recorded when the runnable was constructed.
*
* @return time in milliseconds object was constructed
*/
public long getCreationTime() {
return creationTime;
}
/**
* Blocks until run completed been called the provided qty of times.
*
* @param timeout time to wait for run to be called
* @param expectedRunCount run count to wait for
*/
public void blockTillFinished(int timeout) {
blockTillTrue(timeout, RUN_CONDITION_POLL_INTERVAL);
}
/**
* Call to be overridden to provide a specific action on call.
*/
protected void handleCallStart() {
// ignored by default
}
public long getDelayTillFirstRun() {
return callTime - creationTime;
}
@Override
public Object call() {
callTime = Clock.accurateForwardProgressingMillis();
handleCallStart();
TestUtils.sleep(runDurration);
done = true;
return result;
}
@Override
public boolean get() {
return done;
}
public boolean isDone() {
return done;
}
public Object getReturnedResult() {
return result;
}
}