private async Task PollWorkflows() { try { if (await _lockProvider.AcquireLock("poll runnables", new CancellationToken())) { try { _logger.LogDebug("Polling for runnable workflows"); var runnables = await _persistenceStore.GetRunnableInstances(_dateTimeProvider.Now); foreach (var item in runnables) { if (_persistenceStore.SupportsScheduledCommands) { try { await _persistenceStore.ScheduleCommand(new ScheduledCommand() { CommandName = ScheduledCommand.ProcessWorkflow, Data = item, ExecuteTime = _dateTimeProvider.UtcNow.Ticks }); continue; } catch (Exception ex) { _logger.LogError(ex, ex.Message); } } if (_greylist.Contains($"wf:{item}")) { _logger.LogDebug($"Got greylisted workflow {item}"); continue; } _logger.LogDebug("Got runnable instance {0}", item); _greylist.Add($"wf:{item}"); await _queueProvider.QueueWork(item, QueueType.Workflow); } } finally { await _lockProvider.ReleaseLock("poll runnables"); } } } catch (Exception ex) { _logger.LogError(ex, ex.Message); } }
protected override async Task ProcessItem(string itemId, CancellationToken cancellationToken) { if (!await _lockProvider.AcquireLock($"evt:{itemId}", cancellationToken)) { Logger.LogInformation($"Event locked {itemId}"); return; } try { cancellationToken.ThrowIfCancellationRequested(); var evt = await _eventRepository.GetEvent(itemId, cancellationToken); if (evt.IsProcessed) { _greylist.Add($"evt:{evt.Id}"); return; } if (evt.EventTime <= _datetimeProvider.UtcNow) { IEnumerable <EventSubscription> subs = null; if (evt.EventData is ActivityResult) { var activity = await _subscriptionRepository.GetSubscription((evt.EventData as ActivityResult).SubscriptionId, cancellationToken); if (activity == null) { Logger.LogWarning($"Activity already processed - {(evt.EventData as ActivityResult).SubscriptionId}"); await _eventRepository.MarkEventProcessed(itemId, cancellationToken); return; } subs = new List <EventSubscription> { activity }; } else { subs = await _subscriptionRepository.GetSubscriptions(evt.EventName, evt.EventKey, evt.EventTime, cancellationToken); } var toQueue = new HashSet <string>(); var complete = true; foreach (var sub in subs.ToList()) { complete = complete && await SeedSubscription(evt, sub, toQueue, cancellationToken); } if (complete) { await _eventRepository.MarkEventProcessed(itemId, cancellationToken); } else { _greylist.Remove($"evt:{evt.Id}"); } foreach (var eventId in toQueue) { await QueueProvider.QueueWork(eventId, QueueType.Event); } } } finally { await _lockProvider.ReleaseLock($"evt:{itemId}"); } }
/// <summary> /// Poll the persistence store for workflows ready to run. /// Poll the persistence store for stashed unpublished events /// </summary> private async void PollRunnables(object target) { try { if (await _lockProvider.AcquireLock("poll runnables", new CancellationToken())) { try { _logger.LogInformation("Polling for runnable workflows"); var runnables = await _persistenceStore.GetRunnableInstances(DateTime.Now); foreach (var item in runnables) { if (_greylist.Contains($"wf:{item}")) { _logger.LogDebug($"Got greylisted workflow {item}"); continue; } _logger.LogDebug("Got runnable instance {0}", item); _greylist.Add($"wf:{item}"); await _queueProvider.QueueWork(item, QueueType.Workflow); } } finally { await _lockProvider.ReleaseLock("poll runnables"); } } } catch (Exception ex) { _logger.LogError(ex, ex.Message); } try { if (await _lockProvider.AcquireLock("unprocessed events", new CancellationToken())) { try { _logger.LogInformation("Polling for unprocessed events"); var events = await _persistenceStore.GetRunnableEvents(DateTime.Now); foreach (var item in events.ToList()) { if (_greylist.Contains($"evt:{item}")) { _logger.LogDebug($"Got greylisted event {item}"); _greylist.Add($"evt:{item}"); continue; } _logger.LogDebug($"Got unprocessed event {item}"); _greylist.Add($"evt:{item}"); await _queueProvider.QueueWork(item, QueueType.Event); } } finally { await _lockProvider.ReleaseLock("unprocessed events"); } } } catch (Exception ex) { _logger.LogError(ex, ex.Message); } }