private async Task <int> ResumeCorrelatedWorkflowsAsync(TriggerWorkflowsRequest request, CancellationToken cancellationToken) { var correlationId = request.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 = await _bookmarkFinder.FindBookmarksAsync(request.ActivityType, request.Bookmark, request.TenantId, cancellationToken).ToList(); await ResumeWorkflowsAsync(bookmarkResults, request.Input, cancellationToken); } return(correlatedWorkflowInstanceCount); }
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()); }
public async Task <IActionResult> Handle( [FromQuery(Name = "workflow")] string?workflowDefinitionId = default, [FromQuery(Name = "status")] WorkflowStatus?workflowStatus = default, [FromQuery] string?correlationId = default, [FromQuery] OrderBy?orderBy = default, [FromQuery] string?searchTerm = default, int page = 0, int pageSize = 25, CancellationToken cancellationToken = default) { _stopwatch.Restart(); var specification = Specification <WorkflowInstance> .Identity; if (!string.IsNullOrWhiteSpace(workflowDefinitionId)) { specification = specification.WithWorkflowDefinition(workflowDefinitionId); } if (!string.IsNullOrWhiteSpace(correlationId)) { specification = specification.WithCorrelationId(correlationId); } if (workflowStatus != null) { specification = specification.WithStatus(workflowStatus.Value); } if (!string.IsNullOrWhiteSpace(searchTerm)) { specification = specification.WithSearchTerm(searchTerm); } var orderBySpecification = default(OrderBy <WorkflowInstance>); if (orderBy != null) { orderBySpecification = orderBy switch { OrderBy.Started => OrderBySpecification.OrderByDescending <WorkflowInstance>(x => x.CreatedAt), OrderBy.LastExecuted => OrderBySpecification.OrderByDescending <WorkflowInstance>(x => x.LastExecutedAt !), OrderBy.Finished => OrderBySpecification.OrderByDescending <WorkflowInstance>(x => x.FinishedAt !), _ => OrderBySpecification.OrderByDescending <WorkflowInstance>(x => x.FinishedAt !) }; } var totalCount = await _workflowInstanceStore.CountAsync(specification, cancellationToken : cancellationToken); var paging = Paging.Page(page, pageSize); var workflowInstances = await _workflowInstanceStore.FindManyAsync(specification, orderBySpecification, paging, cancellationToken).ToList(); var items = _mapper.Map <ICollection <WorkflowInstanceSummaryModel> >(workflowInstances); _stopwatch.Stop(); _logger.LogDebug("Handle took {TimeElapsed}", _stopwatch.Elapsed); var model = new PagedList <WorkflowInstanceSummaryModel>(items, page, pageSize, totalCount); return(Json(model, _contentSerializer.GetSettings())); } }
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()); }
private static async Task <bool> WorkflowHasNonFinishedWorkflowsAsync(IWorkflowBlueprint workflowBlueprint, IWorkflowInstanceStore workflowInstanceStore, CancellationToken cancellationToken) { var count = await workflowInstanceStore.CountAsync(new UnfinishedWorkflowSpecification().WithWorkflowDefinition(workflowBlueprint.Id), cancellationToken); return(count > 0); }
public Task <int> CountAsync(ISpecification <WorkflowInstance> specification, CancellationToken cancellationToken = default) => _store.CountAsync(specification, cancellationToken);