/// <summary> /// Handles the next <see cref="IWorkflowActivityProcessor"/>'s <see cref="V1WorkflowActivityCompletedIntegrationEvent"/> /// </summary> /// <param name="processor">The <see cref="IWorkflowActivityProcessor"/> that returned the <see cref="V1WorkflowActivityCompletedIntegrationEvent"/></param> /// <param name="e">The <see cref="V1WorkflowActivityCompletedIntegrationEvent"/> to handle</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/></param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual async Task OnTriggerResultAsync(IWorkflowActivityProcessor processor, V1WorkflowActivityCompletedIntegrationEvent e, CancellationToken cancellationToken) { using (await this.Lock.LockAsync(cancellationToken)) { if (this.Activity.Status == V1WorkflowActivityStatus.Completed) { return; } var completedActivities = (await this.Context.Workflow.GetActivitiesAsync(this.Activity, cancellationToken)) .Where(p => p.Type == V1WorkflowActivityType.EventTrigger && p.Status == V1WorkflowActivityStatus.Completed) .ToList(); if (this.State.Exclusive || completedActivities.Count == this.State.Triggers.Count) { var output = new object(); foreach (var activity in completedActivities .Where(p => p.Output != null)) { output = output.Merge(activity.Output.ToObject()); } await this.OnNextAsync(new V1WorkflowActivityCompletedIntegrationEvent(this.Activity.Id, output), cancellationToken); await this.OnCompletedAsync(cancellationToken); } } }
/// <inheritdoc/> protected override IWorkflowActivityProcessor CreateProcessorFor(V1WorkflowActivity activity) { IWorkflowActivityProcessor processor = base.CreateProcessorFor(activity); CancellationToken cancellationToken = this.CancellationTokenSource.Token; switch (processor) { case ConsumeEventProcessor consumeEventProcessor: processor.OfType <V1WorkflowActivityCompletedIntegrationEvent>().SubscribeAsync ( async result => await this.OnEventResultAsync(consumeEventProcessor, result, cancellationToken), async ex => await this.OnErrorAsync(ex, cancellationToken), async() => await this.OnEventCompletedAsync(consumeEventProcessor, cancellationToken) ); break; case ActionProcessor actionProcessor: processor.OfType <V1WorkflowActivityCompletedIntegrationEvent>().SubscribeAsync ( async result => await this.OnActionResultAsync(actionProcessor, result, cancellationToken), async ex => await this.OnErrorAsync(ex, cancellationToken), async() => await this.OnActionCompletedAsync(actionProcessor, cancellationToken) ); break; default: throw new NotSupportedException($"The specified execution pointer type '{processor.GetType().Name}' is not supported in this context"); } return(processor); }
/// <summary> /// Handles the completion of the specified <see cref="IWorkflowActivityProcessor"/> /// </summary> /// <param name="processor">The <see cref="IWorkflowActivityProcessor"/> to handle the completion of</param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual async Task OnActivityProcessingCompletedAsync(IWorkflowActivityProcessor processor) { this.Processors.TryRemove(processor); processor.Dispose(); foreach (IWorkflowActivityProcessor childProcessor in this.Processors) { await childProcessor.ProcessAsync(this.CancellationToken); } }
/// <summary> /// Handles an <see cref="Exception"/> that has occured during the processing of a <see cref="V1WorkflowActivity"/> /// </summary> /// <param name="processor">The <see cref="IWorkflowActivityProcessor"/> that has thrown the <see cref="Exception"/> to handle</param> /// <param name="ex">The <see cref="Exception"/> to handle</param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual async Task OnActivityProcessingErrorAsync(IWorkflowActivityProcessor processor, Exception ex) { try { this.Logger.LogWarning("An error occured while executing the workflow instance: {ex}", ex.ToString()); await this.Context.Workflow.FaultAsync(ex, this.CancellationToken); this.HostApplicationLifetime.StopApplication(); } catch (Exception cex) { this.Logger.LogError("A critical exception occured while faulting the execution of the workflow instance: {ex}", cex.ToString()); throw; } }
/// <summary> /// Creates a new child <see cref="IWorkflowActivityProcessor"/> for the specified <see cref="V1WorkflowActivity"/> /// </summary> /// <param name="activity">The <see cref="V1WorkflowActivity"/> to create a child <see cref="IWorkflowActivityProcessor"/> for</param> protected virtual IWorkflowActivityProcessor CreateActivityProcessor(V1WorkflowActivity activity) { if (activity == null) { throw new ArgumentNullException(nameof(activity)); } IWorkflowActivityProcessor processor = this.ActivityProcessorFactory.Create(activity); switch (processor) { case IStateProcessor stateProcessor: processor.OfType <V1WorkflowActivityCompletedIntegrationEvent>().SubscribeAsync ( async e => await this.OnStateCompletedAsync(stateProcessor, e), async ex => await this.OnActivityProcessingErrorAsync(stateProcessor, ex), async() => await this.OnActivityProcessingCompletedAsync(stateProcessor) ); break; case ITransitionProcessor transitionProcessor: processor.OfType <V1WorkflowActivityCompletedIntegrationEvent>().SubscribeAsync ( async e => await this.OnTransitionCompletedAsync(transitionProcessor, e), async ex => await this.OnActivityProcessingErrorAsync(transitionProcessor, ex), async() => await this.OnActivityProcessingCompletedAsync(transitionProcessor) ); break; case IEndProcessor endProcessor: processor.OfType <V1WorkflowActivityCompletedIntegrationEvent>().SubscribeAsync ( async e => await this.OnEndCompletedAsync(endProcessor, e), async ex => await this.OnActivityProcessingErrorAsync(endProcessor, ex), async() => await this.OnCompletedAsync(endProcessor) ); break; } this.Processors.Add(processor); return(processor); }
/// <summary> /// Handles the completion of the specified <see cref="IWorkflowActivityProcessor"/> /// </summary> /// <param name="processor">The <see cref="IWorkflowActivityProcessor"/> to handle the completion of</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/></param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual Task OnTriggerCompletedAsync(IWorkflowActivityProcessor processor, CancellationToken cancellationToken) { this.Processors.TryRemove(processor); processor.Dispose(); return(Task.CompletedTask); }