private async ValueTask <bool> CanExecuteAsync(WorkflowExecutionContext workflowExecutionContext, IActivityBlueprint activityBlueprint, bool resuming, CancellationToken cancellationToken) { using var scope = _serviceScopeFactory.CreateScope(); var activityExecutionContext = new ActivityExecutionContext( scope.ServiceProvider, workflowExecutionContext, activityBlueprint, workflowExecutionContext.Input, resuming, cancellationToken); using var executionScope = AmbientActivityExecutionContext.EnterScope(activityExecutionContext); var runtimeActivityInstance = await activityExecutionContext.ActivateActivityAsync(cancellationToken); var activityType = runtimeActivityInstance.ActivityType; var activity = await activityType.ActivateAsync(activityExecutionContext); var canExecute = await activityType.CanExecuteAsync(activityExecutionContext, activity); if (canExecute) { var canExecuteMessage = new ValidateWorkflowActivityExecution(activityExecutionContext, runtimeActivityInstance); await _mediator.Publish(canExecuteMessage, cancellationToken); canExecute = canExecuteMessage.CanExecuteActivity; } return(canExecute); }
private async ValueTask RunCoreAsync(WorkflowExecutionContext workflowExecutionContext, ActivityOperation activityOperation, CancellationToken cancellationToken = default) { var scope = workflowExecutionContext.ServiceProvider; var workflowBlueprint = workflowExecutionContext.WorkflowBlueprint; var workflowInstance = workflowExecutionContext.WorkflowInstance; var burstStarted = false; while (workflowExecutionContext.HasScheduledActivities) { var scheduledActivity = workflowInstance.CurrentActivity = workflowExecutionContext.PopScheduledActivity(); var currentActivityId = scheduledActivity.ActivityId; var activityBlueprint = workflowBlueprint.GetActivity(currentActivityId) !; var resuming = activityOperation == Resume; var outputReference = workflowInstance.Output; var output = outputReference != null ? await _workflowStorageService.LoadAsync(outputReference.ProviderName, new WorkflowStorageContext(workflowInstance, outputReference.ActivityId), "Output", cancellationToken) : null; var input = !burstStarted ? workflowExecutionContext.Input : scheduledActivity.Input ?? output; var activityExecutionContext = new ActivityExecutionContext(scope, workflowExecutionContext, activityBlueprint, input, resuming, cancellationToken); var runtimeActivityInstance = await activityExecutionContext.ActivateActivityAsync(cancellationToken); var activityType = runtimeActivityInstance.ActivityType; using var executionScope = AmbientActivityExecutionContext.EnterScope(activityExecutionContext); var activity = await activityType.ActivateAsync(activityExecutionContext); if (!burstStarted) { await _mediator.Publish(new WorkflowExecutionBurstStarting(workflowExecutionContext, activityExecutionContext), cancellationToken); burstStarted = true; } if (resuming) { await _mediator.Publish(new ActivityResuming(activityExecutionContext, activity), cancellationToken); } await _mediator.Publish(new ActivityExecuting(activityExecutionContext, activity), cancellationToken); var result = await TryExecuteActivityAsync(activityOperation, activityExecutionContext, activity, cancellationToken); if (result == null) { return; } await _mediator.Publish(new ActivityExecuted(activityExecutionContext, activity), cancellationToken); await _mediator.Publish(new ActivityExecutionResultExecuting(result, activityExecutionContext), cancellationToken); await result.ExecuteAsync(activityExecutionContext, cancellationToken); workflowExecutionContext.CompletePass(); workflowInstance.LastExecutedActivityId = currentActivityId; await _mediator.Publish(new ActivityExecutionResultExecuted(result, activityExecutionContext), cancellationToken); await _mediator.Publish(new WorkflowExecutionPassCompleted(workflowExecutionContext, activityExecutionContext), cancellationToken); if (!workflowExecutionContext.HasScheduledActivities) { await _mediator.Publish(new WorkflowExecutionBurstCompleted(workflowExecutionContext, activityExecutionContext), cancellationToken); } activityOperation = Execute; } workflowInstance.CurrentActivity = null; if (workflowExecutionContext.HasBlockingActivities) { workflowExecutionContext.Suspend(); } if (workflowExecutionContext.Status == WorkflowStatus.Running) { await workflowExecutionContext.CompleteAsync(); } }