예제 #1
0
        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);
        }
예제 #2
0
        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();
            }
        }