/* ************************************************************************ # # DivConq # # http://divconq.com/ # # Copyright: # Copyright 2014 eTimeline, LLC. All rights reserved. # # License: # See the license.txt file in the project's top-level directory for details. # # Authors: # * Andy White # ************************************************************************ */ package divconq.script.inst; import java.util.concurrent.ScheduledFuture; import divconq.hub.Hub; import divconq.lang.op.OperationContext; import divconq.script.ExecuteState; import divconq.script.Instruction; import divconq.script.StackEntry; import divconq.work.TaskRun; public class Sleep extends Instruction { @Override public void run(StackEntry stack) { stack.getStore().removeField("Future"); // TODO support Period or Duration also int secs = (int) stack.intFromSource("Seconds"); OperationContext ctx = OperationContext.get(); TaskRun srun = OperationContext.get().getTaskRun(); int omin2 = 0; // if we are inside a task we have only 1 minute, what if sleep is longer? // automatically change timeout for the instruction if (srun != null) { omin2 = srun.getTask().getTimeout(); int pmin = (secs / 60) + 1; // convert sleep to minutes srun.getTask().withTimeout(pmin); // up the timeout for this instruction } int omin = omin2; // TODO review if shutdown leaves Script thread hanging and uncanceled if sleep is long stack.getStore().setField("Future", Hub.instance.getClock().scheduleOnceInternal(() -> { //System.out.println("after sleep point"); stack.getStore().removeField("Future"); // ensure we are working with the correct context during resume OperationContext.set(ctx); if (srun != null) srun.getTask().withTimeout(omin); // restore the original timeout stack.setState(ExecuteState.Done); stack.resume(); }, secs)); } @Override public void cancel(StackEntry stack) { //System.out.println("sleep cancelled"); // avoid race condition ScheduledFuture<?> lf = (ScheduledFuture<?>) stack.getStore().getFieldAsAny("Future"); if (lf != null) { lf.cancel(false); stack.getStore().removeField("Future"); } } }