private async Task TriggerWorkflowsAsync(Message message, CancellationToken cancellationToken) { var correlationId = message.CorrelationId; var model = new MessageModel { Body = message.Body, CorrelationId = message.CorrelationId, ContentType = message.ContentType, Label = message.Label, To = message.To, MessageId = message.MessageId, PartitionKey = message.PartitionKey, ViaPartitionKey = message.ViaPartitionKey, ReplyTo = message.ReplyTo, SessionId = message.SessionId, ExpiresAtUtc = message.ExpiresAtUtc, TimeToLive = message.TimeToLive, ReplyToSessionId = message.ReplyToSessionId, ScheduledEnqueueTimeUtc = message.ScheduledEnqueueTimeUtc, UserProperties = new Dictionary <string, object>(message.UserProperties), }; var bookmark = CreateBookmark(message); var trigger = CreateTrigger(message); var launchContext = new CollectWorkflowsContext(ActivityType, bookmark, trigger, correlationId); await _workflowLaunchpad.UseServiceAsync(service => service.CollectAndDispatchWorkflowsAsync(launchContext, model, cancellationToken)); }
public async Task <IActionResult> Handle(TriggerWorkflowsRequestModel request, CancellationToken cancellationToken = default) { var tenantId = await _tenantAccessor.GetTenantIdAsync(cancellationToken); var context = new CollectWorkflowsContext(request.ActivityType, request.Bookmark, request.Trigger, request.CorrelationId, request.WorkflowInstanceId, request.ContextId, tenantId); ICollection <TriggeredWorkflowModel> triggeredWorkflows; if (request.Dispatch) { var result = await _workflowLaunchpad.CollectAndDispatchWorkflowsAsync(context, request.Input, cancellationToken).ToList(); triggeredWorkflows = result.Select(x => new TriggeredWorkflowModel(x.WorkflowInstanceId, x.ActivityId)).ToList(); } else { var result = await _workflowLaunchpad.CollectAndExecuteWorkflowsAsync(context, request.Input, cancellationToken).ToList(); triggeredWorkflows = result.Select(x => new TriggeredWorkflowModel(x.WorkflowInstanceId, x.ActivityId)).ToList(); } if (Response.HasStarted) { return(new EmptyResult()); } return(Ok(new TriggerWorkflowsResponseModel(triggeredWorkflows))); }
public async Task <IActionResult> Handle(ExecuteWorkflowsRequest request, CancellationToken cancellationToken = default) { var context = new CollectWorkflowsContext(request.ActivityType, request.Bookmark, request.Trigger, request.CorrelationId, request.WorkflowInstanceId, request.ContextId); var result = await _workflowLaunchpad.CollectAndExecuteWorkflowsAsync(context, request.Input, cancellationToken).ToList(); if (Response.HasStarted) { return(new EmptyResult()); } return(Ok(new ExecuteWorkflowsResponse(result))); }
public async Task <IEnumerable <PendingWorkflow> > CollectWorkflowsAsync(CollectWorkflowsContext context, CancellationToken cancellationToken = default) { var correlationId = context.CorrelationId; if (!string.IsNullOrWhiteSpace(correlationId)) { return(await CollectResumableOrStartableCorrelatedWorkflowsAsync(context, cancellationToken)); } if (!string.IsNullOrWhiteSpace(context.WorkflowInstanceId)) { return(await CollectSpecificWorkflowInstanceAsync(context, cancellationToken)); } return(await CollectResumableAndStartableWorkflowsAsync(context, cancellationToken)); }
public async Task Handle(TelnyxWebhookReceived notification, CancellationToken cancellationToken) { var webhook = notification.Webhook; var eventType = webhook.Data.EventType; var payload = webhook.Data.Payload; var activityType = _webhookFilterService.GetActivityTypeName(payload); if (activityType == null) { _logger.LogWarning("The received event '{EventType}' is an unsupported event", webhook.Data.EventType); return; } var correlationId = GetCorrelationId(payload); var bookmark = new NotificationBookmark(eventType); var trigger = new NotificationBookmark(eventType); var context = new CollectWorkflowsContext(activityType, bookmark, trigger, correlationId); await _workflowLaunchpad.CollectAndDispatchWorkflowsAsync(context, webhook, cancellationToken); }
public async Task <IEnumerable <StartableWorkflow> > CollectStartableWorkflowsAsync(CollectWorkflowsContext context, CancellationToken cancellationToken = default) { _logger.LogDebug("Triggering workflows using {ActivityType}", context.ActivityType); var filter = context.Trigger; var triggers = filter != null ? (await _triggerFinder.FindTriggersAsync(context.ActivityType, filter, context.TenantId, cancellationToken)).ToList() : new List <TriggerFinderResult>(); var startableWorkflows = new List <StartableWorkflow>(); foreach (var trigger in triggers) { var workflowBlueprint = trigger.WorkflowBlueprint; var startableWorkflow = await CollectStartableWorkflowAsync(workflowBlueprint, trigger.ActivityId, context.CorrelationId, context.ContextId, context.TenantId, cancellationToken); if (startableWorkflow != null) { startableWorkflows.Add(startableWorkflow); } } return(startableWorkflows); }
private async Task <IEnumerable <PendingWorkflow> > CollectResumableOrStartableCorrelatedWorkflowsAsync(CollectWorkflowsContext context, CancellationToken cancellationToken) { var correlationId = context.CorrelationId !; var lockKey = correlationId; _logger.LogDebug("Acquiring lock on correlation ID {CorrelationId}", correlationId); await using (var handle = await _distributedLockProvider.AcquireLockAsync(lockKey, _elsaOptions.DistributedLockTimeout, cancellationToken)) { if (handle == null) { throw new LockAcquisitionException($"Failed to acquire a lock on {lockKey}"); } var correlatedWorkflowInstanceCount = !string.IsNullOrWhiteSpace(correlationId) ? await _workflowInstanceStore.CountAsync(new CorrelationIdSpecification <WorkflowInstance>(correlationId).WithStatus(WorkflowStatus.Suspended), cancellationToken) : 0; _logger.LogDebug("Found {CorrelatedWorkflowCount} correlated workflows,", correlatedWorkflowInstanceCount); if (correlatedWorkflowInstanceCount > 0) { _logger.LogDebug("{WorkflowInstanceCount} existing workflows found with correlation ID '{CorrelationId}' will be queued for execution", correlatedWorkflowInstanceCount, correlationId); var bookmarkResults = context.Bookmark != null ? await _bookmarkFinder.FindBookmarksAsync(context.ActivityType, context.Bookmark, correlationId, context.TenantId, cancellationToken).ToList() : new List <BookmarkFinderResult>(); return(bookmarkResults.Select(x => new PendingWorkflow(x.WorkflowInstanceId, x.ActivityId)).ToList()); } } var startableWorkflows = await CollectStartableWorkflowsAsync(context, cancellationToken); return(startableWorkflows.Select(x => new PendingWorkflow(x.WorkflowInstance.Id, x.ActivityId)).ToList()); }
private async Task <IEnumerable <PendingWorkflow> > CollectSpecificWorkflowInstanceAsync(CollectWorkflowsContext context, CancellationToken cancellationToken) { var bookmarkResultsQuery = context.Bookmark != null ? await _bookmarkFinder.FindBookmarksAsync(context.ActivityType, context.Bookmark, context.CorrelationId, context.TenantId, cancellationToken) : default; bookmarkResultsQuery = bookmarkResultsQuery?.Where(x => x.WorkflowInstanceId == context.WorkflowInstanceId); var bookmarkResults = bookmarkResultsQuery?.ToList() ?? new List <BookmarkFinderResult>(); var pendingWorkflows = bookmarkResults.Select(x => new PendingWorkflow(x.WorkflowInstanceId, x.ActivityId)).ToList(); return(pendingWorkflows); }
public async Task <IEnumerable <PendingWorkflow> > CollectResumableAndStartableWorkflowsAsync(CollectWorkflowsContext context, CancellationToken cancellationToken) { var bookmarkResultsQuery = context.Bookmark != null ?await _bookmarkFinder.FindBookmarksAsync(context.ActivityType, context.Bookmark, context.CorrelationId, context.TenantId, cancellationToken) : default; var bookmarkResults = bookmarkResultsQuery?.ToList() ?? new List <BookmarkFinderResult>(); var triggeredPendingWorkflows = bookmarkResults.Select(x => new PendingWorkflow(x.WorkflowInstanceId, x.ActivityId)).ToList(); var startableWorkflows = await CollectStartableWorkflowsAsync(context, cancellationToken); var pendingWorkflows = triggeredPendingWorkflows.Concat(startableWorkflows.Select(x => new PendingWorkflow(x.WorkflowInstance.Id, x.ActivityId))).Distinct().ToList(); return(pendingWorkflows); }
public async Task <IEnumerable <PendingWorkflow> > CollectAndDispatchWorkflowsAsync(CollectWorkflowsContext context, object?input = default, CancellationToken cancellationToken = default) { var pendingWorkflows = await CollectWorkflowsAsync(context, cancellationToken).ToList(); await DispatchPendingWorkflowsAsync(pendingWorkflows, input, cancellationToken); return(pendingWorkflows); }
public async Task <IEnumerable <StartedWorkflow> > CollectAndExecuteWorkflowsAsync(CollectWorkflowsContext context, object?input = default, CancellationToken cancellationToken = default) { var pendingWorkflows = await CollectWorkflowsAsync(context, cancellationToken).ToList(); await ExecutePendingWorkflowsAsync(pendingWorkflows, input, cancellationToken); return(pendingWorkflows.Select(x => new StartedWorkflow(x.WorkflowInstanceId, x.ActivityId))); }
public async Task <IEnumerable <StartableWorkflow> > CollectStartableWorkflowsAsync(CollectWorkflowsContext context, CancellationToken cancellationToken = default) { var correlationId = context.CorrelationId ?? Guid.NewGuid().ToString("N"); var updatedContext = context with { CorrelationId = correlationId }; await using var lockHandle = await AcquireLockAsync(correlationId, cancellationToken); return(await CollectStartableWorkflowsInternalAsync(updatedContext, cancellationToken)); }
private async Task <IEnumerable <CollectedWorkflow> > CollectResumableOrStartableCorrelatedWorkflowsAsync(CollectWorkflowsContext context, CancellationToken cancellationToken) { var correlationId = context.CorrelationId !; await using var handle = await AcquireLockAsync(correlationId, cancellationToken); var correlatedWorkflowInstanceCount = !string.IsNullOrWhiteSpace(correlationId) ? await _workflowInstanceStore.CountAsync(new CorrelationIdSpecification <WorkflowInstance>(correlationId).And(new WorkflowUnfinishedStatusSpecification()), cancellationToken) : 0; _logger.LogDebug("Found {CorrelatedWorkflowCount} workflows with correlation ID {CorrelationId}", correlatedWorkflowInstanceCount, correlationId); if (correlatedWorkflowInstanceCount > 0) { var bookmarkResults = context.Bookmark != null ? await _bookmarkFinder.FindBookmarksAsync(context.ActivityType, context.Bookmark, correlationId, context.TenantId, cancellationToken).ToList() : new List <BookmarkFinderResult>(); _logger.LogDebug("Found {BookmarkCount} bookmarks for activity type {ActivityType}", bookmarkResults.Count, context.ActivityType); return(bookmarkResults.Select(x => new CollectedWorkflow(x.WorkflowInstanceId, x.ActivityId)).ToList()); } var startableWorkflows = await CollectStartableWorkflowsInternalAsync(context, cancellationToken); return(startableWorkflows.Select(x => new CollectedWorkflow(x.WorkflowInstance.Id, x.ActivityId)).ToList()); }