protected override async Task ProcessItem(string itemId, CancellationToken cancellationToken) { if (!await _lockProvider.AcquireLock(itemId, cancellationToken)) { Logger.LogInformation("Workflow locked {0}", itemId); return; } WorkflowInstance workflow = null; WorkflowExecutorResult result = null; try { cancellationToken.ThrowIfCancellationRequested(); workflow = await _persistenceStore.GetWorkflowInstance(itemId, cancellationToken); if (workflow.Status == WorkflowStatus.Runnable) { try { result = await _executor.Execute(workflow, cancellationToken); } finally { await _persistenceStore.PersistWorkflow(workflow, cancellationToken); await QueueProvider.QueueWork(itemId, QueueType.Index); _greylist.Remove($"wf:{itemId}"); } } } finally { await _lockProvider.ReleaseLock(itemId); if ((workflow != null) && (result != null)) { foreach (var sub in result.Subscriptions) { await SubscribeEvent(sub, _persistenceStore, cancellationToken); } await _persistenceStore.PersistErrors(result.Errors, cancellationToken); var readAheadTicks = _datetimeProvider.UtcNow.Add(Options.PollInterval).Ticks; if ((workflow.Status == WorkflowStatus.Runnable) && workflow.NextExecution.HasValue && workflow.NextExecution.Value < readAheadTicks) { new Task(() => FutureQueue(workflow, cancellationToken)).Start(); } } } }
/// <summary> /// Worker thread body /// </summary> private async void RunWorkflows() { while (!_shutdown) { try { var workflowId = await _queueProvider.DequeueWork(QueueType.Workflow); if (workflowId != null) { try { if (await _lockProvider.AcquireLock(workflowId)) { WorkflowInstance workflow = null; WorkflowExecutorResult result = null; try { workflow = await _persistenceStore.GetWorkflowInstance(workflowId); if (workflow.Status == WorkflowStatus.Runnable) { try { result = _executor.Execute(workflow, _options); } finally { await _persistenceStore.PersistWorkflow(workflow); } } } finally { await _lockProvider.ReleaseLock(workflowId); if ((workflow != null) && (result != null)) { foreach (var sub in result.Subscriptions) { await SubscribeEvent(sub); } await _persistenceStore.PersistErrors(result.Errors); if ((workflow.Status == WorkflowStatus.Runnable) && workflow.NextExecution.HasValue && workflow.NextExecution.Value < DateTime.Now.ToUniversalTime().Ticks) { await _queueProvider.QueueWork(workflowId, QueueType.Workflow); } } } } else { _logger.LogInformation("Workflow locked {0}", workflowId); } } catch (Exception ex) { _logger.LogError(ex.Message); } } else { await Task.Delay(_options.IdleTime); //no work } } catch (Exception ex) { _logger.LogError(ex.Message); } } }