示例#1
0
        private async Task <RunWorkflowResult> BeginWorkflow(WorkflowExecutionContext workflowExecutionContext, IActivityBlueprint?activity, CancellationToken cancellationToken)
        {
            if (activity == null)
            {
                activity = _startingActivitiesProvider.GetStartActivities(workflowExecutionContext.WorkflowBlueprint).FirstOrDefault() ?? workflowExecutionContext.WorkflowBlueprint.Activities.First();
            }

            try
            {
                if (!await CanExecuteAsync(workflowExecutionContext, activity, false, cancellationToken))
                {
                    return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, false));
                }

                workflowExecutionContext.Begin();
                workflowExecutionContext.ScheduleActivity(activity.Id);
                await RunAsync(workflowExecutionContext, Execute, cancellationToken);

                return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, true));
            }
            catch (Exception e)
            {
                _logger.LogWarning(e, "Failed to run workflow {WorkflowInstanceId}", workflowExecutionContext.WorkflowInstance.Id);
                workflowExecutionContext.Fault(e, null, null, false);
            }

            return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, false));
        }
示例#2
0
        private async Task <RunWorkflowResult> BeginWorkflow(WorkflowExecutionContext workflowExecutionContext, IActivityBlueprint?activity, CancellationToken cancellationToken)
        {
            if (activity == null)
            {
                activity = _startingActivitiesProvider.GetStartActivities(workflowExecutionContext.WorkflowBlueprint).FirstOrDefault() ?? workflowExecutionContext.WorkflowBlueprint.Activities.First();
            }

            try
            {
                if (!await CanExecuteAsync(workflowExecutionContext, activity, false, cancellationToken))
                {
                    return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, null, false));
                }

                var currentStatus = workflowExecutionContext.WorkflowInstance.WorkflowStatus;
                workflowExecutionContext.Begin();
                workflowExecutionContext.ScheduleActivity(activity.Id);
                await _mediator.Publish(new WorkflowStatusChanged(workflowExecutionContext.WorkflowInstance, workflowExecutionContext.WorkflowInstance.WorkflowStatus, currentStatus), cancellationToken);
                await RunCoreAsync(workflowExecutionContext, Execute, cancellationToken);

                return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity?.Id, null, true));
            }
            catch (Exception e)
            {
                _logger.LogWarning(e, "Failed to run workflow {WorkflowInstanceId}", workflowExecutionContext.WorkflowInstance.Id);
                workflowExecutionContext.Fault(e, activity?.Id, null, false);

                if (activity != null)
                {
                    workflowExecutionContext.AddEntry(activity, "Faulted", null, SimpleException.FromException(e));
                }

                return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity?.Id, e, false));
            }
        }
示例#3
0
        private async Task <RunWorkflowResult> ResumeWorkflowAsync(WorkflowExecutionContext workflowExecutionContext, IActivityBlueprint activity, CancellationToken cancellationToken)
        {
            try
            {
                if (!await CanExecuteAsync(workflowExecutionContext, activity, true, cancellationToken))
                {
                    return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, null, false));
                }

                var blockingActivities = workflowExecutionContext.WorkflowInstance.BlockingActivities.Where(x => x.ActivityId == activity.Id).ToList();

                foreach (var blockingActivity in blockingActivities)
                {
                    await workflowExecutionContext.RemoveBlockingActivityAsync(blockingActivity);
                }

                var currentStatus = workflowExecutionContext.WorkflowInstance.WorkflowStatus;
                workflowExecutionContext.Resume();
                workflowExecutionContext.ScheduleActivity(activity.Id);
                await _mediator.Publish(new WorkflowStatusChanged(workflowExecutionContext.WorkflowInstance, workflowExecutionContext.WorkflowInstance.WorkflowStatus, currentStatus), cancellationToken);
                await RunCoreAsync(workflowExecutionContext, Resume, cancellationToken);

                return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, null, true));
            }
            catch (Exception e)
            {
                _logger.LogWarning(e, "Failed to run workflow {WorkflowInstanceId}", workflowExecutionContext.WorkflowInstance.Id);
                workflowExecutionContext.Fault(e, activity.Id, null, false);
                workflowExecutionContext.AddEntry(activity, "Faulted", null, SimpleException.FromException(e));
                return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, e, false));
            }
        }
示例#4
0
        private async Task <RunWorkflowResult> BeginWorkflow(WorkflowExecutionContext workflowExecutionContext, IActivityBlueprint?activity, CancellationToken cancellationToken)
        {
            if (activity == null)
            {
                activity = _startingActivitiesProvider.GetStartActivities(workflowExecutionContext.WorkflowBlueprint).FirstOrDefault() ?? workflowExecutionContext.WorkflowBlueprint.Activities.First();
            }

            if (!await CanExecuteAsync(workflowExecutionContext, activity, false, cancellationToken))
            {
                return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, false));
            }

            workflowExecutionContext.Begin();
            workflowExecutionContext.ScheduleActivity(activity.Id);
            await RunAsync(workflowExecutionContext, Execute, cancellationToken);

            return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activity.Id, true));
        }
示例#5
0
        public override async Task ExecuteAsync(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken)
        {
            var currentActivity = workflowContext.CurrentActivity;
            var previousEntry   = workflowContext.Workflow.ExecutionLog.OrderByDescending(x => x.Timestamp).Skip(steps).FirstOrDefault();

            if (previousEntry == null)
            {
                return;
            }

            var activityId = previousEntry.ActivityId;
            var activity   = workflowContext.Workflow.GetActivity(activityId);

            workflowContext.ScheduleActivity(activity);

            var eventHandlers = workflowContext.ServiceProvider.GetServices <IWorkflowEventHandler>();
            var logger        = workflowContext.ServiceProvider.GetRequiredService <ILogger <GoBackResult> >();
            await eventHandlers.InvokeAsync(x => x.ActivityExecutedAsync(workflowContext, currentActivity, cancellationToken), logger);
        }
示例#6
0
        private async Task <RunWorkflowResult> ResumeWorkflowAsync(WorkflowExecutionContext workflowExecutionContext, IActivityBlueprint activityBlueprint, CancellationToken cancellationToken)
        {
            if (!await CanExecuteAsync(workflowExecutionContext, activityBlueprint, true, cancellationToken))
            {
                return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activityBlueprint.Id, false));
            }

            var blockingActivities = workflowExecutionContext.WorkflowInstance.BlockingActivities.Where(x => x.ActivityId == activityBlueprint.Id).ToList();

            foreach (var blockingActivity in blockingActivities)
            {
                await workflowExecutionContext.RemoveBlockingActivityAsync(blockingActivity);
            }

            workflowExecutionContext.Resume();
            workflowExecutionContext.ScheduleActivity(activityBlueprint.Id);
            await RunAsync(workflowExecutionContext, Resume, cancellationToken);

            return(new RunWorkflowResult(workflowExecutionContext.WorkflowInstance, activityBlueprint.Id, true));
        }
示例#7
0
        public async Task <WorkflowExecutionContext> InvokeAsync(Workflow workflow, IActivity startActivity = default, Variables arguments = default, CancellationToken cancellationToken = default)
        {
            workflow.Arguments = arguments ?? new Variables();
            var workflowExecutionContext = new WorkflowExecutionContext(workflow);
            var isResuming = workflowExecutionContext.Workflow.Status == WorkflowStatus.Resuming;

            if (startActivity != null)
            {
                workflow.BlockingActivities.Remove(startActivity);
            }
            else
            {
                startActivity = workflow.Activities.First();
            }

            workflowExecutionContext.Workflow.Status = WorkflowStatus.Executing;
            workflowExecutionContext.ScheduleActivity(startActivity);

            while (workflowExecutionContext.HasScheduledActivities)
            {
                var currentActivity = workflowExecutionContext.PopScheduledActivity();
                var result          = await ExecuteActivityAsync(workflowExecutionContext, currentActivity, isResuming, cancellationToken);

                if (result == null)
                {
                    break;
                }

                await result.ExecuteAsync(this, workflowExecutionContext, cancellationToken);

                workflowExecutionContext.IsFirstPass = false;
                isResuming = false;
            }

            if (workflowExecutionContext.Workflow.Status != WorkflowStatus.Halted)
            {
                workflowExecutionContext.Finish();
            }

            return(workflowExecutionContext);
        }
示例#8
0
        private async Task <bool> ResumeWorkflowAsync(WorkflowExecutionContext workflowExecutionContext, IActivityBlueprint activityBlueprint, object?input, CancellationToken cancellationToken)
        {
            if (!await CanExecuteAsync(workflowExecutionContext, activityBlueprint, input, true, cancellationToken))
            {
                return(false);
            }

            var blockingActivities = workflowExecutionContext.WorkflowInstance.BlockingActivities.Where(x => x.ActivityId == activityBlueprint.Id).ToList();

            foreach (var blockingActivity in blockingActivities)
            {
                workflowExecutionContext.WorkflowInstance.BlockingActivities.Remove(blockingActivity);
                await _mediator.Publish(new BlockingActivityRemoved(workflowExecutionContext, blockingActivity), cancellationToken);
            }

            workflowExecutionContext.Resume();
            workflowExecutionContext.ScheduleActivity(activityBlueprint.Id, input);
            await RunAsync(workflowExecutionContext, Resume, cancellationToken);

            return(true);
        }
示例#9
0
 protected override void Execute(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext)
 {
     workflowContext.ScheduleActivity(activity);
 }
示例#10
0
        public async Task <WorkflowExecutionContext> InvokeAsync(Workflow workflow, IActivity startActivity = default, Variables arguments = default, CancellationToken cancellationToken = default)
        {
            workflow.Arguments = arguments ?? new Variables();
            var workflowExecutionContext = new WorkflowExecutionContext(workflow);
            var isResuming = workflowExecutionContext.Workflow.Status == WorkflowStatus.Resuming;

            // If a start activity was provided, remove it from the blocking activities list. If not start activity was provided, pick the first one that has no inbound connections.
            if (startActivity != null)
            {
                workflow.BlockingActivities.Remove(startActivity);
            }
            else
            {
                startActivity = workflow.GetStartActivities().FirstOrDefault();
            }

            if (!isResuming)
            {
                workflow.StartedAt = clock.GetCurrentInstant();
            }

            workflowExecutionContext.Workflow.Status = WorkflowStatus.Executing;

            if (startActivity != null)
            {
                workflowExecutionContext.ScheduleActivity(startActivity);
            }

            // Keep executing activities as long as there are any scheduled.
            while (workflowExecutionContext.HasScheduledActivities)
            {
                var currentActivity = workflowExecutionContext.PopScheduledActivity();
                var result          = await ExecuteActivityAsync(workflowExecutionContext, currentActivity, isResuming, cancellationToken);

                if (result == null)
                {
                    break;
                }

                await result.ExecuteAsync(this, workflowExecutionContext, cancellationToken);

                workflowExecutionContext.IsFirstPass = false;
                isResuming = false;
            }

            // Any other status than Halted means the workflow has ended (either because it reached the final activity, was aborted or has faulted).
            if (workflowExecutionContext.Workflow.Status != WorkflowStatus.Halted)
            {
                workflowExecutionContext.Finish(clock.GetCurrentInstant());
            }
            else
            {
                // Persist workflow before executing the halted activities.
                await workflowStore.SaveAsync(workflow, cancellationToken);

                // Invoke Halted event on activity drivers that halted the workflow.
                while (workflowExecutionContext.HasScheduledHaltingActivities)
                {
                    var currentActivity = workflowExecutionContext.PopScheduledHaltingActivity();
                    var result          = await ExecuteActivityHaltedAsync(workflowExecutionContext, currentActivity, cancellationToken);

                    await result.ExecuteAsync(this, workflowExecutionContext, cancellationToken);
                }
            }

            await workflowStore.SaveAsync(workflow, cancellationToken);

            return(workflowExecutionContext);
        }