/** * @see #transform(Task, Function) */ @SuppressWarnings({ "rawtypes" }) public static <U,T> Task<T> transform(final Map flags, final TaskAdaptable<U> task, final Function<U,T> transformer) { return new BasicTask<T>(flags, new Callable<T>() { @Override public T call() throws Exception { if (!task.asTask().isSubmitted()) { BasicExecutionContext.getCurrentExecutionContext().submit(task); } return transformer.apply(task.asTask().get()); }}); }
@Override public void blockUntilEnded() { blockUntilEnded(null); }
@Override public final synchronized boolean cancel(boolean mayInterruptIfRunning) { // semantics changed in 2016-01, previously "true" was INTERRUPT_TASK_BUT_NOT_SUBMITTED_TASKS return cancel(mayInterruptIfRunning ? TaskCancellationMode.INTERRUPT_TASK_AND_DEPENDENT_SUBMITTED_TASKS : TaskCancellationMode.DO_NOT_INTERRUPT); }
/** * Returns true if the task has had an error. * * Only true if calling {@link #get()} will throw an exception when it completes (including cancel). * Implementations may set this true before completion if they have that insight, or * (the default) they may compute it lazily after completion (returning false before completion). */ @Override public boolean isError() { if (!isDone()) return false; if (isCancelled()) return true; try { get(); return false; } catch (Throwable t) { return true; } }
@Override public T get() throws InterruptedException, ExecutionException { try { if (!isDone()) Tasks.setBlockingTask(this); blockUntilStarted(); return internalFuture.get(); } finally { Tasks.resetBlockingTask(); } }
@Test public void cancelAfterRun() throws Exception { BasicTask<Integer> t = new BasicTask<Integer>(Callables.returning(42)); em.submit(MutableMap.of("tag", "A"), t); assertEquals(t.get(), (Integer)42); t.cancel(true); assertFalse(t.isCancelled()); assertFalse(t.isError()); assertTrue(t.isDone()); }
if (callableOrSupplier instanceof BasicTask) { fakeTaskForContext = (BasicTask<?>)callableOrSupplier; if (fakeTaskForContext.isQueuedOrSubmitted()) { if (fakeTaskForContext.isDone()) { return Maybe.of((T)fakeTaskForContext.getUnchecked()); } else { throw new ImmediateUnsupportedException("Task is in progress and incomplete: "+fakeTaskForContext); callableOrSupplier = fakeTaskForContext.getJob(); } else { fakeTaskForContext = new BasicTask<Object>(MutableMap.of("displayName", "immediate evaluation")); registerPerThreadExecutionContext(); if (previousTask!=null) fakeTaskForContext.setSubmittedByTask(previousTask); fakeTaskForContext.cancel(); try { BasicExecutionManager.getPerThreadCurrentTask().set(fakeTaskForContext);
else if (!isCancelled() && startTimeUtc <= 0) { rv = "Submitted for execution"; if (verbosity>0) { if (verbosity >= 2 && getExtraStatusText()!=null) { rv += "\n\n"+getExtraStatusText(); } else if (isDone()) { long elapsed = endTimeUtc - submitTimeUtc; String duration = Time.makeTimeStringRounded(elapsed); if (isCancelled()) { rv = "Cancelled"; if (verbosity >= 1) rv+=" after "+duration; if (verbosity >= 2 && getExtraStatusText()!=null) { rv += "\n\n"+getExtraStatusText(); } else if (isError()) { rv = "Failed"; if (verbosity >= 1) { if (verbosity >= 2 && getExtraStatusText()!=null) { rv += "\n\n"+getExtraStatusText(); if (verbosity == 1) rv += ": "+abbreviate(errorMessage); if (verbosity >= 2) { rv += ": "+errorMessage; if (verbosity==1) {
@Test public void testSequentialTaskFailsWhenIntermediateTaskThrowsException() throws Exception { BasicTask<String> t1 = taskReturning("a"); BasicTask<String> t2 = new BasicTask<String>(new Callable<String>() { @Override public String call() throws Exception { throw new IllegalArgumentException("forced exception"); } }); BasicTask<String> t3 = taskReturning("c"); SequentialTask<String> task = new SequentialTask<String>(t1, t2, t3); Task<List<String>> tSequence = ec.submit(task); try { tSequence.get(); fail("t2 should have thrown an exception"); } catch (Exception e) {} assertTrue(task.isDone()); assertTrue(task.isError()); assertTrue(t1.isDone()); assertFalse(t1.isError()); assertTrue(t2.isDone()); assertTrue(t2.isError()); // t3 not run because of t2 exception assertFalse(t3.isDone()); assertFalse(t3.isBegun()); }
@Test public void fieldsSetForSimpleBasicTask() throws Exception { final CountDownLatch signalStarted = new CountDownLatch(1); final CountDownLatch allowCompletion = new CountDownLatch(1); BasicTask<Integer> t = new BasicTask<Integer>(new Callable<Integer>() { @Override public Integer call() throws Exception { signalStarted.countDown(); allowCompletion.await(); return 42; }}); assertEquals(null, t.getSubmittedByTask()); assertEquals(-1, t.submitTimeUtc); assertNull(t.getInternalFuture()); em.submit(MutableMap.of("tag", "A"), t); assertTrue(signalStarted.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); assertTrue(t.submitTimeUtc > 0); assertTrue(t.startTimeUtc >= t.submitTimeUtc); assertNotNull(t.getInternalFuture()); assertEquals(-1, t.endTimeUtc); assertEquals(false, t.isCancelled()); allowCompletion.countDown(); assertEquals(t.get(), (Integer)42); assertTrue(t.endTimeUtc >= t.startTimeUtc); log.debug("BasicTask duration (millis): {}", (t.endTimeUtc - t.submitTimeUtc)); }
final CountDownLatch signalStarted = new CountDownLatch(1); final CountDownLatch allowCompletion = new CountDownLatch(1); final BasicTask<Object> t = new BasicTask<Object>(new Callable<Object>() { @Override public Object call() throws Exception { assertFalse(t.isDone()); assertFalse(t.isDone()); log.debug("runBasicTaskWithWaits, BasicTask status: {}", t.getStatusDetail(false)); assertEquals("a", t.get());
@Test public void fieldsSetForBasicTaskSubmittedBasicTask() throws Exception { BasicTask<Integer> t = new BasicTask<Integer>(MutableMap.of("displayName", "sample", "description", "some descr"), new Callable<Integer>() { @Override public Integer call() throws Exception { em.submit(MutableMap.of("tag", "A"), t); t.blockUntilEnded(); assertEquals( 46, tb.get() ); assertEquals( t, em.getTasksWithTag("A").iterator().next() ); assertNull( t.getSubmittedByTask() ); BasicTask<?> submitter = (BasicTask<?>) tb.getSubmittedByTask(); assertNotNull(submitter); assertEquals("sample", submitter.displayName);
@Test public void runParallelTaskWithDelay() throws Exception { final Semaphore locker = new Semaphore(0); BasicTask<String> t1 = new BasicTask<String>(new Callable<String>() { @Override public String call() { try { final Task<List<String>> tSequence = ec.submit(new ParallelTask<String>(t4, t2, t1, t3)); assertEquals(ImmutableSet.of(t2.get(), t3.get(), t4.get()), ImmutableSet.of("b", "c", "d")); assertFalse(t1.isDone()); assertFalse(tSequence.isDone()); assertTrue(t1.isDone()); assertTrue(tSequence.isDone());
protected String getActiveTaskStatusString(int verbosity) { String rv = ""; Thread t = getThread(); if (isDone()) { return getStatusString(verbosity); } else { if (getThread()==null) return getStatusString(verbosity); if (getExtraStatusText()!=null) { rv += getExtraStatusText()+"\n\n"; rv += ""+toString()+"\n"; if (submittedByTask!=null) { rv += "Submitted by "+submittedByTask+"\n"; rv +=", thread waiting "; if (ti.getThreadState() == Thread.State.BLOCKED) { rv += "(mutex) on "+lookup(lock); rv += "(notify) on "+lookup(lock); } else if (ti.getThreadState() == Thread.State.TIMED_WAITING) { rv += "(timed) on "+lookup(lock); } else { rv = "("+ti.getThreadState()+") on "+lookup(lock);
@Test(groups="Integration") public void testFinalizerInvoked() throws InterruptedException { BasicTask<?> t = new BasicTask<Void>(new Runnable() { @Override public void run() { /* no op */ }}); final Semaphore x = new Semaphore(0); t.setFinalizer(new BasicTask.TaskFinalizer() { @Override public void onTaskFinalization(Task<?> t) { synchronized (x) { x.release(); } } }); t = null; Stopwatch watch = Stopwatch.createStarted(); for (int i=0; i<30; i++) { System.gc(); System.gc(); if (x.tryAcquire(1, TimeUnit.SECONDS)) { log.info("finalizer ran after "+Time.makeTimeStringRounded(watch)); return; } } Assert.fail("finalizer did not run in time"); }
@Override public T getUnchecked() { try { return get(); } catch (Exception e) { throw Exceptions.propagate(e); } }
public void setFinalizer(TaskFinalizer f) { TaskFinalizer finalizer = Tasks.tag(this, TaskFinalizer.class, false); if (finalizer!=null && finalizer!=f) throw new IllegalStateException("Cannot apply multiple finalizers"); if (isDone()) throw new IllegalStateException("Finalizer cannot be set on task "+this+" after it is finished"); tags.add(f); }
public void ignoreIfNotRun() { setFinalizer(NO_OP); }