public async Task DispatchAsync(ExecuteWorkflowInstanceRequest request, CancellationToken cancellationToken = default) { var workflowInstance = await _workflowInstanceStore.FindByIdAsync(request.WorkflowInstanceId, cancellationToken); if (workflowInstance == null) { _logger.LogWarning("Cannot dispatch a workflow instance ID that does not exist"); return; } var workflowBlueprint = await _workflowRegistry.GetAsync(workflowInstance.DefinitionId, workflowInstance.TenantId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken); if (workflowBlueprint == null) { _logger.LogWarning("Workflow instance {WorkflowInstanceId} references workflow blueprint {WorkflowDefinitionId} with version {Version}, but could not be found", workflowInstance.Id, workflowInstance.DefinitionId, workflowInstance.Version); return; } var channel = _workflowChannelOptions.GetChannelOrDefault(workflowBlueprint.Channel); var queue = ServiceBusOptions.FormatChannelQueueName <ExecuteWorkflowInstanceRequest>(channel); await _commandSender.SendAsync(request, queue, cancellationToken : cancellationToken); }
public async Task <StartableWorkflow?> CollectStartableWorkflowAsync(string workflowDefinitionId, string?activityId, string?correlationId = default, string?contextId = default, string?tenantId = default, CancellationToken cancellationToken = default) { var workflowBlueprint = await _workflowRegistry.GetAsync(workflowDefinitionId, tenantId, VersionOptions.Published, cancellationToken); if (workflowBlueprint == null) { return(null); } return(await CollectStartableWorkflowAsync(workflowBlueprint, activityId, correlationId, contextId, tenantId, cancellationToken)); }
public async Task DispatchAsync(ExecuteWorkflowDefinitionRequest request, CancellationToken cancellationToken = default) { var workflowBlueprint = await _workflowRegistry.GetAsync(request.WorkflowDefinitionId, request.TenantId, VersionOptions.Published, cancellationToken); if (workflowBlueprint == null) { _logger.LogWarning("No published version found for workflow blueprint {WorkflowDefinitionId}", request.WorkflowDefinitionId); return; } var channel = _workflowChannelOptions.GetChannelOrDefault(workflowBlueprint.Channel); var queue = ElsaOptions.FormatChannelQueueName <ExecuteWorkflowDefinitionRequest>(channel); EnqueueJob <WorkflowDefinitionJob>(x => x.ExecuteAsync(request, CancellationToken.None), queue); }
public async Task <Unit> Handle(ExecuteWorkflowDefinitionRequest request, CancellationToken cancellationToken) { var workflowDefinitionId = request.WorkflowDefinitionId; var tenantId = request.TenantId; var workflowBlueprint = await _workflowRegistry.GetAsync(workflowDefinitionId, tenantId, VersionOptions.Published, cancellationToken); if (!ValidatePreconditions(workflowDefinitionId, workflowBlueprint)) { return(Unit.Value); } var lockKey = $"execute-workflow-definition:tenant:{tenantId}:workflow-definition:{workflowDefinitionId}"; var correlationId = request.CorrelationId; var correlationLockHandle = default(IDistributedSynchronizationHandle?); if (!string.IsNullOrWhiteSpace(correlationId)) { _logger.LogDebug("Acquiring lock on correlation ID {CorrelationId}", correlationId); correlationLockHandle = await _distributedLockProvider.AcquireLockAsync(correlationId, _elsaOptions.DistributedLockTimeout, cancellationToken); if (correlationLockHandle == null) { throw new LockAcquisitionException($"Failed to acquire a lock on correlation ID {correlationId}"); } } try { await using var handle = await _distributedLockProvider.AcquireLockAsync(lockKey, _elsaOptions.DistributedLockTimeout, cancellationToken); if (handle == null) { throw new LockAcquisitionException($"Failed to acquire a lock on {lockKey}"); } if (!workflowBlueprint !.IsSingleton || await GetWorkflowIsAlreadyExecutingAsync(tenantId, workflowDefinitionId) == false) { await _startsWorkflow.StartWorkflowAsync(workflowBlueprint, request.ActivityId, request.Input, request.CorrelationId, request.ContextId, cancellationToken); } } finally { if (correlationLockHandle != null) { await correlationLockHandle.DisposeAsync(); } } return(Unit.Value); }
public async Task <ActionResult <WorkflowBlueprintModel> > Handle(string id, VersionOptions?versionOptions = default, CancellationToken cancellationToken = default) { versionOptions ??= VersionOptions.Latest; var workflowBlueprint = await _workflowRegistry.GetAsync(id, null, versionOptions.Value, cancellationToken, true); if (workflowBlueprint == null) { return(NotFound()); } var model = await _workflowBlueprintMapper.MapAsync(workflowBlueprint, cancellationToken); return(Json(model, _contentSerializer.GetSettings())); }
public async Task <RunWorkflowResult> ResumeWorkflowAsync(WorkflowInstance workflowInstance, string?activityId = default, object?input = default, CancellationToken cancellationToken = default) { var workflowBlueprint = await _workflowRegistry.GetAsync( workflowInstance.DefinitionId, workflowInstance.TenantId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken); if (workflowBlueprint == null) { throw new WorkflowException($"Workflow instance {workflowInstance.Id} references workflow definition {workflowInstance.DefinitionId} version {workflowInstance.Version}, but no such workflow definition was found."); } return(await _workflowRunner.RunWorkflowAsync(workflowBlueprint, workflowInstance, activityId, input, cancellationToken)); }
public async Task <RunWorkflowResult?> FindAndRestartTestWorkflowAsync( string workflowDefinitionId, string activityId, int version, string signalRConnectionId, string lastWorkflowInstanceId, string?tenantId = default, CancellationToken cancellationToken = default) { var workflowBlueprint = await _workflowRegistry.GetAsync(workflowDefinitionId, tenantId, VersionOptions.SpecificVersion(version), cancellationToken); if (workflowBlueprint == null) { return(null); } var lastWorkflowInstance = await _workflowInstanceStore.FindAsync(new EntityIdSpecification <WorkflowInstance>(lastWorkflowInstanceId), cancellationToken); if (lastWorkflowInstance == null) { return(null); } var startActivity = workflowBlueprint.Activities.First(x => x.Id == activityId); var startableWorkflowDefinition = new StartableWorkflowDefinition(workflowBlueprint, startActivity.Id); var workflow = await InstantiateStartableWorkflow(startableWorkflowDefinition, cancellationToken); var previousActivityData = GetActivityDataFromLastWorkflowInstance(workflow.WorkflowInstance, lastWorkflowInstance, workflowBlueprint, activityId); MergeActivityDataIntoInstance(workflow.WorkflowInstance, previousActivityData); SetMetadata(workflow.WorkflowInstance, signalRConnectionId); //if previousActivityOutput has any items, then the first one is from activity closest to the starting one var previousActivityOutput = previousActivityData.Count == 0 ? null : previousActivityData.First().Value?.GetItem("Output"); return(await ExecuteStartableWorkflowAsync(workflow, new WorkflowInput(previousActivityOutput), cancellationToken)); }
public async Task Handle(ExecuteWorkflowDefinitionRequest message) { var workflowDefinitionId = message.WorkflowDefinitionId; var tenantId = message.TenantId; var workflowBlueprint = await _workflowRegistry.GetAsync(workflowDefinitionId, tenantId, VersionOptions.Published); if (workflowBlueprint == null) { _logger.LogWarning("Could not find workflow with ID {WorkflowDefinitionId}", workflowDefinitionId); return; } var startableWorkflow = await _workflowLaunchpad.CollectStartableWorkflowAsync(workflowBlueprint, message.ActivityId, message.CorrelationId, message.ContextId, tenantId); if (startableWorkflow == null) { _logger.LogDebug("Could not start workflow with ID {WorkflowDefinitionId}", workflowDefinitionId); return; } await _workflowLaunchpad.ExecuteStartableWorkflowAsync(startableWorkflow, message.Input); }
private async Task <IWorkflowBlueprint?> GetWorkflowBlueprintAsync(WorkflowInstance workflowInstance, CancellationToken cancellationToken) => await _workflowRegistry.GetAsync(workflowInstance.DefinitionId, workflowInstance.TenantId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken);
public static Task <IWorkflowBlueprint?> GetWorkflowAsync <T>( this IWorkflowRegistry workflowRegistry, string?tenantId, CancellationToken cancellationToken = default) => workflowRegistry.GetAsync(typeof(T).Name, tenantId, VersionOptions.Latest, cancellationToken);