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)); }
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)); } }
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)); } }
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)); }
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); }
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)); }
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); }
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); }
protected override void Execute(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext) { workflowContext.ScheduleActivity(activity); }
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); }