mirror of https://github.com/apache/cassandra
InterceptingExecutor.schedule returns a simulator-unsafe Future
patch by Benedict Elliott Smith; reviewed by David Capwell for CASSANDRA-20420
This commit is contained in:
parent
fa1157203f
commit
ab556ab545
|
|
@ -91,43 +91,9 @@ public interface InterceptingExecutor extends OrderOn
|
|||
|
||||
OrderOn orderAppliesAfterScheduling();
|
||||
|
||||
static class InterceptedScheduledFutureTask<T> extends SyncFutureTask<T> implements ScheduledFuture<T>
|
||||
interface InterceptableScheduledFuture<T> extends ScheduledFuture<T>, RunnableFuture<T>
|
||||
{
|
||||
final long delayNanos;
|
||||
Runnable onCancel;
|
||||
public InterceptedScheduledFutureTask(long delayNanos, Callable<T> call)
|
||||
{
|
||||
super(call);
|
||||
this.delayNanos = delayNanos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelay(TimeUnit unit)
|
||||
{
|
||||
return unit.convert(delayNanos, NANOSECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Delayed that)
|
||||
{
|
||||
return Long.compare(delayNanos, that.getDelay(NANOSECONDS));
|
||||
}
|
||||
|
||||
void onCancel(Runnable onCancel)
|
||||
{
|
||||
this.onCancel = onCancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean b)
|
||||
{
|
||||
if (onCancel != null)
|
||||
{
|
||||
onCancel.run();
|
||||
onCancel = null;
|
||||
}
|
||||
return super.cancel(b);
|
||||
}
|
||||
void onCancel(Runnable onCancel);
|
||||
}
|
||||
|
||||
@PerClassLoader
|
||||
|
|
@ -715,6 +681,45 @@ public interface InterceptingExecutor extends OrderOn
|
|||
@PerClassLoader
|
||||
class InterceptingSequentialExecutor extends AbstractSingleThreadedExecutorPlus implements InterceptingExecutor, ScheduledExecutorPlus, OrderOn
|
||||
{
|
||||
static class InterceptableScheduledFutureTask<T> extends SyncFutureTask<T> implements InterceptableScheduledFuture<T>
|
||||
{
|
||||
final long delayNanos;
|
||||
Runnable onCancel;
|
||||
public InterceptableScheduledFutureTask(long delayNanos, Callable<T> call)
|
||||
{
|
||||
super(call);
|
||||
this.delayNanos = delayNanos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelay(TimeUnit unit)
|
||||
{
|
||||
return unit.convert(delayNanos, NANOSECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Delayed that)
|
||||
{
|
||||
return Long.compare(delayNanos, that.getDelay(NANOSECONDS));
|
||||
}
|
||||
|
||||
public void onCancel(Runnable onCancel)
|
||||
{
|
||||
this.onCancel = onCancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean b)
|
||||
{
|
||||
if (onCancel != null)
|
||||
{
|
||||
onCancel.run();
|
||||
onCancel = null;
|
||||
}
|
||||
return super.cancel(b);
|
||||
}
|
||||
}
|
||||
|
||||
InterceptingSequentialExecutor(InterceptorOfExecution interceptorOfExecution, ThreadFactory threadFactory, InterceptingTaskFactory taskFactory)
|
||||
{
|
||||
super(interceptorOfExecution, threadFactory, taskFactory);
|
||||
|
|
@ -765,7 +770,7 @@ public interface InterceptingExecutor extends OrderOn
|
|||
throw new RejectedExecutionException();
|
||||
|
||||
long delayNanos = unit.toNanos(delay);
|
||||
return interceptorOfExecution.intercept().schedule(SCHEDULED_TASK, delayNanos, relativeToGlobalNanos(delayNanos), callable(run, null), this);
|
||||
return schedule(SCHEDULED_TASK, delayNanos, relativeToGlobalNanos(delayNanos), callable(run, null));
|
||||
}
|
||||
|
||||
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
|
||||
|
|
@ -774,7 +779,7 @@ public interface InterceptingExecutor extends OrderOn
|
|||
throw new RejectedExecutionException();
|
||||
|
||||
long delayNanos = unit.toNanos(delay);
|
||||
return interceptorOfExecution.intercept().schedule(SCHEDULED_TASK, delayNanos, relativeToGlobalNanos(delayNanos), callable, this);
|
||||
return schedule(SCHEDULED_TASK, delayNanos, relativeToGlobalNanos(delayNanos), callable);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> scheduleTimeoutWithDelay(Runnable run, long delay, TimeUnit unit)
|
||||
|
|
@ -787,7 +792,7 @@ public interface InterceptingExecutor extends OrderOn
|
|||
if (isShutdown)
|
||||
throw new RejectedExecutionException();
|
||||
|
||||
return interceptorOfExecution.intercept().schedule(SCHEDULED_TASK, localToRelativeNanos(deadlineNanos), localToGlobalNanos(deadlineNanos), callable(run, null), this);
|
||||
return schedule(SCHEDULED_TASK, localToRelativeNanos(deadlineNanos), localToGlobalNanos(deadlineNanos), callable(run, null));
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> scheduleTimeoutAt(Runnable run, long deadlineNanos)
|
||||
|
|
@ -795,7 +800,7 @@ public interface InterceptingExecutor extends OrderOn
|
|||
if (isShutdown)
|
||||
throw new RejectedExecutionException();
|
||||
|
||||
return interceptorOfExecution.intercept().schedule(SCHEDULED_TIMEOUT, localToRelativeNanos(deadlineNanos), localToGlobalNanos(deadlineNanos), callable(run, null), this);
|
||||
return schedule(SCHEDULED_TIMEOUT, localToRelativeNanos(deadlineNanos), localToGlobalNanos(deadlineNanos), callable(run, null));
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> scheduleSelfRecurring(Runnable run, long delay, TimeUnit unit)
|
||||
|
|
@ -804,7 +809,7 @@ public interface InterceptingExecutor extends OrderOn
|
|||
throw new RejectedExecutionException();
|
||||
|
||||
long delayNanos = unit.toNanos(delay);
|
||||
return interceptorOfExecution.intercept().schedule(SCHEDULED_DAEMON, delayNanos, relativeToGlobalNanos(delayNanos), callable(run, null), this);
|
||||
return schedule(SCHEDULED_DAEMON, delayNanos, relativeToGlobalNanos(delayNanos), callable(run, null));
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> scheduleAtFixedRate(Runnable run, long initialDelay, long period, TimeUnit unit)
|
||||
|
|
@ -813,7 +818,7 @@ public interface InterceptingExecutor extends OrderOn
|
|||
throw new RejectedExecutionException();
|
||||
|
||||
long delayNanos = unit.toNanos(initialDelay);
|
||||
return interceptorOfExecution.intercept().schedule(SCHEDULED_DAEMON, delayNanos, relativeToGlobalNanos(delayNanos), new Callable<Object>()
|
||||
return schedule(SCHEDULED_DAEMON, delayNanos, relativeToGlobalNanos(delayNanos), new Callable<Object>()
|
||||
{
|
||||
@Override
|
||||
public Object call()
|
||||
|
|
@ -829,7 +834,12 @@ public interface InterceptingExecutor extends OrderOn
|
|||
{
|
||||
return run.toString();
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
}
|
||||
|
||||
<T> ScheduledFuture<T> schedule(SimulatedAction.Kind kind, long delayNanos, long deadlineNanos, Callable<T> task)
|
||||
{
|
||||
return interceptorOfExecution.intercept().schedule(kind, delayNanos, deadlineNanos, new InterceptableScheduledFutureTask<>(delayNanos, task), this);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable run, long initialDelay, long delay, TimeUnit unit)
|
||||
|
|
@ -843,6 +853,8 @@ public interface InterceptingExecutor extends OrderOn
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@PerClassLoader
|
||||
class InterceptingPooledLocalAwareExecutor extends InterceptingPooledExecutor implements LocalAwareExecutorPlus
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@
|
|||
|
||||
package org.apache.cassandra.simulator.systems;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.cassandra.simulator.systems.InterceptingExecutor.InterceptableScheduledFuture;
|
||||
import org.apache.cassandra.simulator.systems.SimulatedAction.Kind;
|
||||
import org.apache.cassandra.utils.Shared;
|
||||
import org.apache.cassandra.utils.concurrent.RunnableFuture;
|
||||
|
|
@ -38,7 +38,7 @@ public interface InterceptorOfExecution
|
|||
interface InterceptExecution
|
||||
{
|
||||
<V, T extends RunnableFuture<V>> T addTask(T task, InterceptingExecutor executor);
|
||||
<T> ScheduledFuture<T> schedule(Kind kind, long delayNanos, long deadlineNanos, Callable<T> runnable, InterceptingExecutor executor);
|
||||
<T> ScheduledFuture<T> schedule(Kind kind, long delayNanos, long deadlineNanos, InterceptableScheduledFuture<T> task, InterceptingExecutor executor);
|
||||
Thread start(Kind kind, Function<Runnable, InterceptibleThread> factory, Runnable run);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import org.apache.cassandra.simulator.Actions;
|
|||
import org.apache.cassandra.simulator.OrderOn;
|
||||
import org.apache.cassandra.simulator.systems.InterceptedExecution.InterceptedFutureTaskExecution;
|
||||
import org.apache.cassandra.simulator.systems.InterceptedExecution.InterceptedThreadStart;
|
||||
import org.apache.cassandra.simulator.systems.InterceptingExecutor.InterceptedScheduledFutureTask;
|
||||
import org.apache.cassandra.simulator.systems.InterceptingExecutor.InterceptableScheduledFuture;
|
||||
import org.apache.cassandra.utils.concurrent.Condition;
|
||||
import org.apache.cassandra.utils.concurrent.NotScheduledFuture;
|
||||
import org.apache.cassandra.utils.concurrent.RunnableFuture;
|
||||
|
|
@ -93,7 +93,7 @@ public class SimulatedExecution implements InterceptorOfExecution
|
|||
return task;
|
||||
}
|
||||
|
||||
public <T> ScheduledFuture<T> schedule(SimulatedAction.Kind kind, long delayNanos, long deadlineNanos, Callable<T> runnable, InterceptingExecutor executor)
|
||||
public <T> ScheduledFuture<T> schedule(SimulatedAction.Kind kind, long delayNanos, long deadlineNanos, InterceptableScheduledFuture<T> task, InterceptingExecutor executor)
|
||||
{
|
||||
return new NotScheduledFuture<>();
|
||||
}
|
||||
|
|
@ -135,10 +135,9 @@ public class SimulatedExecution implements InterceptorOfExecution
|
|||
return task;
|
||||
}
|
||||
|
||||
public <V> ScheduledFuture<V> schedule(SimulatedAction.Kind kind, long delayNanos, long deadlineNanos, Callable<V> call, InterceptingExecutor executor)
|
||||
public <V> ScheduledFuture<V> schedule(SimulatedAction.Kind kind, long delayNanos, long deadlineNanos, InterceptableScheduledFuture<V> task, InterceptingExecutor executor)
|
||||
{
|
||||
assert kind == SCHEDULED_TASK || kind == SCHEDULED_TIMEOUT || kind == SCHEDULED_DAEMON;
|
||||
InterceptedScheduledFutureTask<V> task = new InterceptedScheduledFutureTask<>(delayNanos, call);
|
||||
InterceptedFutureTaskExecution<?> intercepted = new InterceptedFutureTaskExecution<>(kind, executor, task, deadlineNanos);
|
||||
task.onCancel(intercepted::cancel);
|
||||
intercept.interceptExecution(intercepted, executor.orderAppliesAfterScheduling());
|
||||
|
|
|
|||
Loading…
Reference in New Issue