/// <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);
                }
            }
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
 /// <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);
     }
 }
Пример #4
0
        /// <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;
            }
        }
Пример #5
0
        /// <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);
 }