public void Execute(Envelope envelope, ContinuationContext context) { _task = Task.Factory.StartNew(() => { var continuation = _inner(); continuation.Execute(envelope, context); }); }
// Signal task completion public void SetCompleted() { // First, mark task as completed or exit if already done. if (Interlocked.CompareExchange(ref _isTaskCompleted, 1, 0) == 1) { return; } // Spin until any pending continuation subscriptions have completed. while (_subscriptionsInProgress > 0) { Thread.SpinWait(20); } // Now, execute all queued continuations. if (_isFirstContinuationQueued == 1) { ExecuteContinuation(in _firstContinuation, isAsyncExecution: true); _firstContinuation = default; } if (_additionalContinuations != null) { while (_additionalContinuations.TryDequeue(out var ctx)) { ExecuteContinuation(in ctx, isAsyncExecution: true); } } }
public void Execute(Envelope envelope, ContinuationContext context) { context.SendFailureAcknowledgement(envelope, "Moved message {0} to the Error Queue.\n{1}".ToFormat(envelope.CorrelationId, _exception)); var report = new ErrorReport(envelope, _exception); envelope.Callback.MoveToErrors(report); }
// Handle continuations subscribed by awaiters void IValueTaskSource.OnCompleted(Action <object> continuation, object state, short _, ValueTaskSourceOnCompletedFlags flags) { var ctx = new ContinuationContext { Continuation = continuation, State = state }; CaptureThreadContext(ref ctx, flags); // Coordinate with concurrent SetCompleted() calls: // Increment the subscriptionsInProgress count and read the task state, in that order. Interlocked.Increment(ref _subscriptionsInProgress); if (_isTaskCompleted == 1) { // Task completed, execute the continuation immediately. Interlocked.Decrement(ref _subscriptionsInProgress); ExecuteContinuation(in ctx, isAsyncExecution: false); } else { // Enqueue the continuation for asynchronous execution. if (Interlocked.CompareExchange(ref _isFirstContinuationQueued, 1, 0) == 0) { // this is the first continuation, store directly to field. _firstContinuation = ctx; } else { // this is a secondary continuation, add to a heap allocated queue. var contQueue = GetOrCreateAdditionalContinuationQueue(); contQueue.Enqueue(ctx); } // signal that the continuation enqueue operation has completed Interlocked.Decrement(ref _subscriptionsInProgress); } }
private static void CaptureThreadContext(ref ContinuationContext destination, ValueTaskSourceOnCompletedFlags flags) { if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0) { destination.ExecutionContext = ExecutionContext.Capture(); } if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0) { SynchronizationContext?sc = SynchronizationContext.Current; if (sc != null && sc.GetType() != typeof(SynchronizationContext)) { destination.Scheduler = sc; } else { TaskScheduler ts = TaskScheduler.Default; if (ts != TaskScheduler.Default) { destination.Scheduler = ts; } } } }
public void Execute(Envelope envelope, ContinuationContext context) { envelope.Callback.MoveToDelayedUntil(context.SystemTime.UtcNow().Add(_delay)); }
public void Execute(Envelope envelope, ContinuationContext context) { throw new NotImplementedException(); }
public void Execute(Envelope envelope, ContinuationContext context) { envelope.Callback.Requeue(); }
public void Execute(Envelope envelope, ContinuationContext context) { context.Pipeline.Invoke(envelope); }
public void Execute(Envelope envelope, ContinuationContext context) { context.SendOutgoingMessages(envelope, new[] { Message }); }
public override void Execute(Envelope envelope, ContinuationContext context) { envelope.Callback.MarkSuccessful(); }
public void Execute(Envelope envelope, ContinuationContext context) { ++Counter; }