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); }