public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var httpMethod = context.HttpContext.Request.Method; var routeValues = context.RouteData.Values; var workflowTypeEntries = await _workflowTypeRouteEntries.GetWorkflowRouteEntriesAsync(httpMethod, routeValues); var workflowEntries = await _workflowRouteEntries.GetWorkflowRouteEntriesAsync(httpMethod, routeValues); if (workflowTypeEntries.Any()) { var workflowTypeIds = workflowTypeEntries.Select(x => Int32.Parse(x.WorkflowId)).ToList(); var workflowTypes = (await _workflowTypeStore.GetAsync(workflowTypeIds)).ToDictionary(x => x.Id); var correlationId = routeValues.GetValue <string>("correlationid"); foreach (var entry in workflowTypeEntries) { if (workflowTypes.TryGetValue(Int32.Parse(entry.WorkflowId), out var workflowType)) { var activity = workflowType.Activities.Single(x => x.ActivityId == entry.ActivityId); if (activity.IsStart) { // If this is not a singleton workflow or there is not already an halted instance, start a new workflow. if (!workflowType.IsSingleton || !await _workflowStore.HasHaltedInstanceAsync(workflowType.WorkflowTypeId)) { await _workflowManager.StartWorkflowAsync(workflowType, activity, null, correlationId); } } } } } if (workflowEntries.Any()) { var workflowIds = workflowEntries.Select(x => x.WorkflowId).ToList(); var workflows = (await _workflowStore.GetAsync(workflowIds)).ToDictionary(x => x.WorkflowId); var correlationId = routeValues.GetValue <string>("correlationid"); foreach (var entry in workflowEntries) { if (workflows.TryGetValue(entry.WorkflowId, out var workflow) && (String.IsNullOrWhiteSpace(correlationId) || workflow.CorrelationId == correlationId)) { var blockingActivity = workflow.BlockingActivities.Single(x => x.ActivityId == entry.ActivityId); await _workflowManager.ResumeWorkflowAsync(workflow, blockingActivity); } } } await next(); }
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var httpMethod = context.HttpContext.Request.Method; var routeValues = context.RouteData.Values; var workflowTypeEntries = await _workflowTypeRouteEntries.GetWorkflowRouteEntriesAsync(httpMethod, routeValues); var workflowEntries = await _workflowRouteEntries.GetWorkflowRouteEntriesAsync(httpMethod, routeValues); if (workflowTypeEntries.Any()) { var workflowTypeIds = workflowTypeEntries.Select(x => Int32.Parse(x.WorkflowId)).ToList(); var workflowTypes = (await _workflowTypeStore.GetAsync(workflowTypeIds)).ToDictionary(x => x.Id); var correlationId = routeValues.GetValue <string>("correlationid"); foreach (var entry in workflowTypeEntries) { if (workflowTypes.TryGetValue(Int32.Parse(entry.WorkflowId), out var workflowType)) { var activity = workflowType.Activities.Single(x => x.ActivityId == entry.ActivityId); if (activity.IsStart) { // If a singleton, try to acquire a lock per workflow type. (var locker, var locked) = await _distributedLock.TryAcquireWorkflowTypeLockAsync(workflowType); if (!locked) { continue; } await using var acquiredLock = locker; // Check if this is a workflow singleton and there's already an halted instance on any activity. if (workflowType.IsSingleton && await _workflowStore.HasHaltedInstanceAsync(workflowType.WorkflowTypeId)) { continue; } await _workflowManager.StartWorkflowAsync(workflowType, activity, null, correlationId); } } } } if (workflowEntries.Any()) { var workflowIds = workflowEntries.Select(x => x.WorkflowId).ToList(); var workflows = (await _workflowStore.GetAsync(workflowIds)).ToDictionary(x => x.WorkflowId); var correlationId = routeValues.GetValue <string>("correlationid"); foreach (var entry in workflowEntries) { if (workflows.TryGetValue(entry.WorkflowId, out var workflow) && (String.IsNullOrWhiteSpace(correlationId) || workflow.CorrelationId == correlationId)) { // If atomic, try to acquire a lock per workflow instance. (var locker, var locked) = await _distributedLock.TryAcquireWorkflowLockAsync(workflow); if (!locked) { continue; } await using var acquiredLock = locker; // If atomic, check if the workflow still exists and is still correlated. var haltedWorkflow = workflow.IsAtomic ? await _workflowStore.GetAsync(workflow.Id) : workflow; if (haltedWorkflow == null || (!String.IsNullOrWhiteSpace(correlationId) && haltedWorkflow.CorrelationId != correlationId)) { continue; } // And if it is still halted on this activity. var blockingActivity = haltedWorkflow.BlockingActivities.SingleOrDefault(x => x.ActivityId == entry.ActivityId); if (blockingActivity != null) { await _workflowManager.ResumeWorkflowAsync(haltedWorkflow, blockingActivity); } } } } await next(); }