예제 #1
0
        private async Task ResumeIdleWorkflows(CancellationToken cancellationToken)
        {
            var instances = await _workflowInstanceStore.FindManyAsync(new WorkflowStatusSpecification(WorkflowStatus.Idle), cancellationToken : cancellationToken).ToList();

            if (instances.Any())
            {
                _logger.LogInformation("Found {WorkflowInstanceCount} workflows with status 'Idle'. Resuming each one of them", instances.Count);
            }
            else
            {
                _logger.LogInformation("Found no workflows with status 'Id'. Nothing to resume");
            }

            foreach (var instance in instances)
            {
                await using var correlationLockHandle = await _distributedLockProvider.AcquireLockAsync(instance.CorrelationId, _elsaOptions.DistributedLockTimeout, cancellationToken);

                if (correlationLockHandle == null)
                {
                    _logger.LogWarning("Failed to acquire lock on correlation {CorrelationId} for workflow instance {WorkflowInstanceId}", instance.CorrelationId, instance.Id);
                    continue;
                }

                _logger.LogInformation("Resuming {WorkflowInstanceId}", instance.Id);

                var input = await GetWorkflowInputAsync(instance, cancellationToken);

                await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(instance.Id, Input : input), cancellationToken);
            }
        }
        public async Task Execute(IJobExecutionContext context)
        {
            var dataMap            = context.MergedJobDataMap;
            var cancellationToken  = context.CancellationToken;
            var workflowInstanceId = dataMap.GetString("WorkflowInstanceId") !;
            var activityId         = dataMap.GetString("ActivityId") !;

            await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(workflowInstanceId, activityId), cancellationToken);
        }
예제 #3
0
        public async Task ExecuteAsync(CancellationToken cancellationToken = default)
        {
            await using var handle = await _distributedLockProvider.AcquireLockAsync(GetType ().Name, _elsaOptions.DistributedLockTimeout, cancellationToken);

            if (handle == null)
            {
                return;
            }

            var instances = await _workflowInstanceStore.FindManyAsync(new WorkflowStatusSpecification(WorkflowStatus.Running), cancellationToken : cancellationToken).ToList();

            if (instances.Any())
            {
                _logger.LogInformation("Found {WorkflowInstanceCount} workflows with status 'Running'. Resuming each one of them", instances.Count);
            }
            else
            {
                _logger.LogInformation("Found no workflows with status 'Running'. Nothing to resume");
            }

            foreach (var instance in instances)
            {
                await using var correlationLockHandle = await _distributedLockProvider.AcquireLockAsync(instance.CorrelationId, _elsaOptions.DistributedLockTimeout, cancellationToken);

                if (handle == null)
                {
                    _logger.LogWarning("Failed to acquire lock on correlation {CorrelationId} for workflow instance {WorkflowInstanceId}", instance.CorrelationId, instance.Id);
                    continue;
                }

                _logger.LogInformation("Resuming {WorkflowInstanceId}", instance.Id);
                var scheduledActivities = instance.ScheduledActivities;

                if (instance.CurrentActivity == null && !scheduledActivities.Any())
                {
                    if (instance.BlockingActivities.Any())
                    {
                        _logger.LogWarning(
                            "Workflow '{WorkflowInstanceId}' was in the Running state, but has no scheduled activities not has a currently executing one. However, it does have blocking activities, so switching to Suspended status",
                            instance.Id);

                        instance.WorkflowStatus = WorkflowStatus.Suspended;
                        await _workflowInstanceStore.SaveAsync(instance, cancellationToken);

                        continue;
                    }

                    _logger.LogWarning("Workflow '{WorkflowInstanceId}' was in the Running state, but has no scheduled activities nor has a currently executing one", instance.Id);
                    continue;
                }

                var scheduledActivity = instance.CurrentActivity ?? instance.ScheduledActivities.Peek();

                await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(instance.Id, scheduledActivity.ActivityId), cancellationToken);
            }
        }
예제 #4
0
        public async Task <WorkflowInstance> ReviveAndQueueAsync(WorkflowInstance workflowInstance, CancellationToken cancellationToken)
        {
            workflowInstance = await ReviveAsync(workflowInstance, cancellationToken);

            var currentActivity = await GetActivityToScheduleAsync(workflowInstance, cancellationToken);

            await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(workflowInstance.Id, currentActivity.ActivityId, currentActivity.Input), cancellationToken);

            return(workflowInstance);
        }
        public async Task Execute(IJobExecutionContext context)
        {
            var dataMap            = context.MergedJobDataMap;
            var cancellationToken  = context.CancellationToken;
            var workflowInstanceId = dataMap.GetString("WorkflowInstanceId") !;
            var activityId         = dataMap.GetString("ActivityId") !;

            using var loggingScope = _logger.BeginScope(new Dictionary <string, object> { ["WorkflowInstanceId"] = workflowInstanceId });
            await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(workflowInstanceId, activityId), cancellationToken);
        }
예제 #6
0
 public async Task ExecuteAsync(RunHangfireWorkflowJobModel data)
 {
     if (data.WorkflowInstanceId == null)
     {
         await _workflowDefinitionDispatcher.DispatchAsync(new ExecuteWorkflowDefinitionRequest(data.WorkflowDefinitionId !, data.ActivityId, TenantId : data.TenantId));
     }
     else
     {
         await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(data.WorkflowInstanceId, data.ActivityId));
     }
 }
예제 #7
0
        public async Task <string> Get()
        {
            var workflow = await workflowRegistry.FindAsync(f => f.Name == "TestWorkFlow");

            var instance = await workflowFactory.InstantiateAsync(workflow);

            await workflowInstanceStore.AddAsync(instance);

            await workflowInvoker.RunWorkflowAsync(workflow, instance);

            await workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(instance.Id, "activity-start"));

            return(instance.Id);
        }
예제 #8
0
        public async Task Execute(IJobExecutionContext context)
        {
            var dataMap              = context.MergedJobDataMap;
            var cancellationToken    = context.CancellationToken;
            var workflowInstanceId   = dataMap.GetString("WorkflowInstanceId");
            var tenantId             = dataMap.GetString("TenantId");
            var workflowDefinitionId = dataMap.GetString("WorkflowDefinitionId") !;
            var activityId           = dataMap.GetString("ActivityId") !;

            if (workflowInstanceId == null)
            {
                await _workflowDefinitionDispatcher.DispatchAsync(new ExecuteWorkflowDefinitionRequest(workflowDefinitionId, activityId, TenantId : tenantId), cancellationToken);
            }
            else
            {
                await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(workflowInstanceId, activityId), cancellationToken);
            }
        }
예제 #9
0
 public async Task DispatchPendingWorkflowAsync(PendingWorkflow pendingWorkflow, object?input, CancellationToken cancellationToken = default) =>
 await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(pendingWorkflow.WorkflowInstanceId, pendingWorkflow.ActivityId, input), cancellationToken);