/** Starts a retriable task */ private Promise<? extends T> run(Context context) { _startedAt = System.currentTimeMillis(); Task<T> task = wrap(0); context.run(task); return task; } }
@Override protected Promise<? extends T> run(final Context context) throws Exception { final SettablePromise<T> result = Promises.settable(); Task<?> prevTask = _tasks.get(0); for (int i = 1; i < _tasks.size(); i++) { final Task<?> currTask = _tasks.get(i); context.after(prevTask).run(currTask); prevTask = currTask; } // This is unsafe, but we don't have the ability to do type checking // with varargs. @SuppressWarnings("unchecked") final Task<T> typedPrevTask = (Task<T>) prevTask; Promises.propagateResult(typedPrevTask, result); context.run(_tasks.get(0)); _tasks = null; return result; } }
@Override public Promise<List<Integer>> run(final Context ctx) { // Save the start time so we can determine when to finish _startMillis = System.currentTimeMillis(); // Set up timeouts for responses long lastWaitTime = Integer.MAX_VALUE; for (final long waitTime : WAIT_TIMES) { if (waitTime < lastWaitTime && waitTime > 0) { ctx.createTimer(waitTime, TimeUnit.MILLISECONDS, checkDone()); lastWaitTime = waitTime; } } // Issue requests for (int i = 0; i < REQUEST_LATENCIES.length; i++) { final long requestLatency = REQUEST_LATENCIES[i]; final Task<Integer> callSvc = callService("subSearch[" + i + "]", _service, new SimpleMockRequest<Integer>(requestLatency, i)); ctx.run(seq(callSvc, addResponse(callSvc), checkDone())); } return _result; }
/** * This method returns Task that returns value for a single key allowing this strategy to batch operations. * @param desc description of the task * @param key key * @return Task that returns value for a single key allowing this strategy to batch operations */ public Task<T> batchable(final String desc, final K key) { Task<T> batchableTask = Task.async(desc, ctx -> { final BatchPromise<T> result = new BatchPromise<>(); final Long planId = ctx.getPlanId(); final GroupBatchBuilder builder = _batches.computeIfAbsent(planId, k -> new GroupBatchBuilder()); final G group = classify(key); Batch<K, T> fullBatch = builder.add(group, key, ctx.getShallowTraceBuilder(), result); if (fullBatch != null) { try { ctx.run(taskForBatch(group, fullBatch, true)); } catch (Throwable t) { //we don't care if some of promises have already been completed //all we care is that all remaining promises have been failed fullBatch.failAll(t); } } return result; }); batchableTask.getShallowTraceBuilder().setTaskType("batched"); return batchableTask; }
throw new RuntimeException(desc + " returned null"); } else { ctx.runSideEffect(sideEffect); }); context.after(that).run(sideEffectWrapper); context.run(that); return sideEffectWrapper; });
} else if (transitionRun(traceContext.getParent().getTraceBuilder())) { markTaskStarted(); traceContext.getParent().getTaskLogger().logTaskStart(this); } else { addPotentialRelationships(traceContext, traceContext.getParent().getTraceBuilder()); Promises.propagateResult(settable, dest);
final TraceBuilder traceBuilder = ctx.getTraceBuilder(); for (BatchEntry<T> entry : batch.values()) { for (ShallowTraceBuilder shallowTraceBuilder: entry.getShallowTraceBuilders()) { if (!assignedParent && !hasParent) { traceBuilder.addRelationship(Relationship.CHILD_OF, ctx.getShallowTraceBuilder(), shallowTraceBuilder); assignedParent = true; } else { traceBuilder.addRelationship(Relationship.POTENTIAL_CHILD_OF, ctx.getShallowTraceBuilder(), shallowTraceBuilder); ctx.getShallowTraceBuilder().setSystemHidden(true);
@Override public Promise<String> run(final Context context) throws Exception { context.createTimer(50, TimeUnit.MILLISECONDS, timerTask); return promise; } };
private void addPotentialRelationships(final FusionTraceContext traceContext, final TraceBuilder builder) { final ShallowTraceBuilder effectoveShallowTraceBuilder = getEffectiveShallowTraceBuilder(traceContext); builder.addRelationship(Relationship.POTENTIAL_CHILD_OF, effectoveShallowTraceBuilder, traceContext.getParent().getShallowTraceBuilder()); if (_predecessorShallowTraceBuilder != null) { builder.addRelationship(Relationship.POSSIBLE_SUCCESSOR_OF, effectoveShallowTraceBuilder, _predecessorShallowTraceBuilder); } }
@Override public void run() throws Exception { context.after(TestUtil.noop()); } });
@Override protected Promise<R> run(final Context context) throws Exception { Executor executor = (Executor) context.getEngineProperty(CALLABLE_SERVICE_EXECUTOR); if (executor == null) { throw new IllegalStateException( "To use AsyncCallableTask you must first register an executor with the engine using AsyncCallableTask.register"); } final SettablePromise<R> promise = Promises.settable(); executor.execute(() -> { try { promise.done(_syncJob.call()); } catch (Throwable t) { promise.fail(t); } } ); return promise; } }
throw new RuntimeException(desc + " returned null"); } else { ctx.runSideEffect(sideEffect); }); context.after(that).run(sideEffectWrapper); context.run(that); return sideEffectWrapper; });
/** * This method returns Task that returns value for a single key allowing this strategy to batch operations. * @param desc description of the task * @param key key * @return Task that returns value for a single key allowing this strategy to batch operations */ public Task<T> batchable(final String desc, final K key) { Task<T> batchableTask = Task.async(desc, ctx -> { final BatchPromise<T> result = new BatchPromise<>(); final Long planId = ctx.getPlanId(); final GroupBatchBuilder builder = _batches.computeIfAbsent(planId, k -> new GroupBatchBuilder()); final G group = classify(key); Batch<K, T> fullBatch = builder.add(group, key, ctx.getShallowTraceBuilder(), result); if (fullBatch != null) { try { ctx.run(taskForBatch(group, fullBatch, true)); } catch (Throwable t) { //we don't care if some of promises have already been completed //all we care is that all remaining promises have been failed fullBatch.failAll(t); } } return result; }); batchableTask.getShallowTraceBuilder().setTaskType("batched"); return batchableTask; }
@Override public final void contextRun(final Context context, final Task<?> parent, final Collection<Task<?>> predecessors) { final TaskLogger taskLogger = context.getTaskLogger(); final TraceBuilder traceBuilder = context.getTraceBuilder(); if (transitionRun(traceBuilder)) { markTaskStarted();
final TraceBuilder traceBuilder = ctx.getTraceBuilder(); for (BatchEntry<T> entry : batch.values()) { for (ShallowTraceBuilder shallowTraceBuilder: entry.getShallowTraceBuilders()) { if (!assignedParent && !hasParent) { traceBuilder.addRelationship(Relationship.CHILD_OF, ctx.getShallowTraceBuilder(), shallowTraceBuilder); assignedParent = true; } else { traceBuilder.addRelationship(Relationship.POTENTIAL_CHILD_OF, ctx.getShallowTraceBuilder(), shallowTraceBuilder); ctx.getShallowTraceBuilder().setSystemHidden(true);
/** Invoke event monitors and schedule a retry if policy allows. */ private void retry(int attempt, Throwable error, ErrorClassification errorClassification, Context recoveryContext, SettablePromise<T> recoveryResult) { long backoffTime = _policy.getBackoffPolicy().nextBackoff(attempt, error); if (errorClassification == ErrorClassification.UNRECOVERABLE) { // For fatal errors there are no retries. LOGGER.debug(String.format("Attempt %s of %s interrupted: %s", attempt, _name, error.getMessage())); recoveryResult.fail(error); } else if (_policy.getTerminationPolicy().shouldTerminate(attempt, System.currentTimeMillis() - _startedAt + backoffTime)) { // Retry policy commands that no more retries should be done. LOGGER.debug(String.format("Too many exceptions after attempt %s of %s, aborting: %s", attempt, _name, error.getMessage())); recoveryResult.fail(error); } else { // Schedule a new retry task after a computed backoff timeout. LOGGER.debug(String.format("Attempt %s of %s failed and will be retried after %s millis: %s", attempt, _name, backoffTime, error.getMessage())); Task<T> retryTask = wrap(attempt); Promises.propagateResult(retryTask, recoveryResult); recoveryContext.createTimer(backoffTime, TimeUnit.MILLISECONDS, retryTask); } }
private void addRelationships(final FusionTraceContext traceContext) { final ShallowTraceBuilder effectoveShallowTraceBuilder = getEffectiveShallowTraceBuilder(traceContext); TraceBuilder builder = getTraceBuilder(); builder.addRelationship(Relationship.PARENT_OF, traceContext.getParent().getShallowTraceBuilder(), effectoveShallowTraceBuilder); if (_predecessorShallowTraceBuilder != null) { builder.addRelationship(Relationship.SUCCESSOR_OF, effectoveShallowTraceBuilder, _predecessorShallowTraceBuilder); } }
@Override protected Promise<R> run(final Context context) throws Exception { Executor executor = (Executor) context.getEngineProperty(CALLABLE_SERVICE_EXECUTOR); if (executor == null) { throw new IllegalStateException( "To use AsyncCallableTask you must first register an executor with the engine using AsyncCallableTask.register"); } final SettablePromise<R> promise = Promises.settable(); executor.execute(() -> { try { promise.done(_syncJob.call()); } catch (Throwable t) { promise.fail(t); } } ); return promise; } }
@Override public Promise<String> run(final Context context) throws Exception { context.run(innerTask); return innerTask; } };