Example #1
0
        private async Task ScheduleStartAtWorkflowsAsync(CancellationToken cancellationToken)
        {
            // Schedule workflow instances that are blocked on a start-at.
            var bookmarkResults = await _bookmarkFinder.FindBookmarksAsync <StartAt>(tenantId : TenantId, cancellationToken : cancellationToken);

            foreach (var result in bookmarkResults)
            {
                var bookmark = (StartAtBookmark)result.Bookmark;
                await _workflowScheduler.ScheduleWorkflowAsync(null, result.WorkflowInstanceId !, result.ActivityId, TenantId, bookmark.ExecuteAt, null, cancellationToken);
            }
        }
Example #2
0
        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);
        }
        private async Task <int> TriggerWorkflowsAsync(TriggerWorkflowsRequest request, CancellationToken cancellationToken)
        {
            var bookmarkResultsQuery = await _bookmarkFinder.FindBookmarksAsync(request.ActivityType, request.Bookmark, request.TenantId, cancellationToken);

            var bookmarkResults = bookmarkResultsQuery.ToList();
            var triggeredCount  = bookmarkResults.GroupBy(x => x.WorkflowInstanceId).Select(x => x.Key).Distinct().Count();

            await ResumeWorkflowsAsync(bookmarkResults, request.Input, cancellationToken);

            var startedCount = await StartWorkflowsAsync(request, cancellationToken);

            return(startedCount + triggeredCount);
        }
Example #4
0
        public async Task <int> Handle(TriggerWorkflowsRequest request, CancellationToken cancellationToken)
        {
            var correlationId = request.CorrelationId;

            if (!string.IsNullOrWhiteSpace(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);
                }
            }

            return(await StartWorkflowsAsync(request, cancellationToken));
        }
 public static Task <IEnumerable <BookmarkFinderResult> > FindBookmarksAsync <T>(
     this IBookmarkFinder bookmarkFinder,
     IBookmark bookmark,
     string?correlationId = default,
     string?tenantId      = default,
     CancellationToken cancellationToken = default) where T : IActivity =>
 bookmarkFinder.FindBookmarksAsync(typeof(T).Name, new[] { bookmark }, correlationId, tenantId, cancellationToken);
 public static Task <IEnumerable <BookmarkFinderResult> > FindBookmarksAsync(
     this IBookmarkFinder bookmarkFinder,
     string activityType,
     IBookmark bookmark,
     string?tenantId,
     CancellationToken cancellationToken = default) =>
 bookmarkFinder.FindBookmarksAsync(activityType, new[] { bookmark }, tenantId, cancellationToken);
Example #7
0
        private async Task ScheduleStartAtWorkflowsAsync(CancellationToken cancellationToken)
        {
            // Schedule workflow instances that are blocked on a start-at.
            var bookmarkResults = await _bookmarkFinder.FindBookmarksAsync <StartAt>(tenantId : TenantId, cancellationToken : cancellationToken).ToList();

            _logger.LogDebug("Found {BookmarkResultCount} bookmarks for StartAt", bookmarkResults.Count);
            var index = 0;

            foreach (var result in bookmarkResults)
            {
                var bookmark = (StartAtBookmark)result.Bookmark;
                await _workflowScheduler.ScheduleAsync(result.WorkflowInstanceId !, result.ActivityId, bookmark.ExecuteAt, null, cancellationToken);

                index++;
                _logger.LogDebug("Scheduled {CurrentBookmarkIndex} of {BookmarkResultCount}", index, bookmarkResults.Count);
            }
        }
Example #8
0
 public static Task <IEnumerable <BookmarkFinderResult> > FindBookmarksAsync <T>(
     this IBookmarkFinder bookmarkFinder,
     string?correlationId = default,
     string?tenantId      = default,
     int skip             = 0,
     int take             = int.MaxValue,
     CancellationToken cancellationToken = default) where T : IActivity =>
 bookmarkFinder.FindBookmarksAsync(typeof(T).GetSimpleAssemblyQualifiedName(), Enumerable.Empty <IBookmark>(), correlationId, tenantId, skip, take, cancellationToken);
Example #9
0
 public static Task <IEnumerable <BookmarkFinderResult> > FindBookmarksAsync(
     this IBookmarkFinder bookmarkFinder,
     string activityType,
     IBookmark bookmark,
     string?correlationId = default,
     string?tenantId      = default,
     int skip             = 0,
     int take             = int.MaxValue,
     CancellationToken cancellationToken = default) =>
 bookmarkFinder.FindBookmarksAsync(activityType, new[] { bookmark }, correlationId, tenantId, skip, take, cancellationToken);
Example #10
0
        public async Task FindAndResumeWorkflowsAsync(
            string activityType,
            IBookmark bookmark,
            string?tenantId,
            WorkflowInput?input  = default,
            string?correlationId = default,
            string?contextId     = default,
            CancellationToken cancellationToken = default)
        {
            var results = await _bookmarkFinder.FindBookmarksAsync(activityType, bookmark, correlationId, tenantId, cancellationToken : cancellationToken).ToList();

            await ResumeWorkflowsAsync(results, input, cancellationToken);
        }
Example #11
0
        private async IAsyncEnumerable <RunWorkflowResult> InterruptActivityTypeInternalAsync(string activityType, WorkflowInput?input, [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            var bookmarks = await _bookmarkFinder.FindBookmarksAsync(activityType, Enumerable.Empty <IBookmark>(), cancellationToken : cancellationToken);

            var workflowInstanceIds = bookmarks.Select(x => x.WorkflowInstanceId).Distinct().ToList();
            var workflowInstances   = await _workflowInstanceStore.FindManyAsync(new ManyWorkflowInstanceIdsSpecification(workflowInstanceIds), cancellationToken : cancellationToken);

            foreach (var workflowInstance in workflowInstances)
            {
                var results = await InterruptActivityTypeAsync(workflowInstance, activityType, input, cancellationToken);

                foreach (var result in results)
                {
                    yield return(result);
                }
            }
        }
 public static Task <IEnumerable <BookmarkFinderResult> > FindBookmarksAsync <T>(
     this IBookmarkFinder bookmarkFinder,
     string?tenantId,
     CancellationToken cancellationToken = default) where T : IActivity =>
 bookmarkFinder.FindBookmarksAsync(typeof(T).Name, Enumerable.Empty <IBookmark>(), tenantId, cancellationToken);