private async Task <bool> SeedSubscription(Event evt, EventSubscription sub, List <string> toQueue, CancellationToken cancellationToken) { foreach (var eventId in await _persistenceStore.GetEvents(sub.EventName, sub.EventKey, sub.SubscribeAsOf)) { if (eventId == evt.Id) { continue; } var siblingEvent = await _persistenceStore.GetEvent(eventId); if ((!siblingEvent.IsProcessed) && (siblingEvent.EventTime < evt.EventTime)) { await QueueProvider.QueueWork(eventId, QueueType.Event); return(false); } if (!siblingEvent.IsProcessed) { toQueue.Add(siblingEvent.Id); } } if (!await _lockProvider.AcquireLock(sub.WorkflowId, cancellationToken)) { Logger.LogInformation("Workflow locked {0}", sub.WorkflowId); return(false); } try { var workflow = await _persistenceStore.GetWorkflowInstance(sub.WorkflowId); var pointers = workflow.ExecutionPointers.Where(p => p.EventName == sub.EventName && p.EventKey == sub.EventKey && !p.EventPublished && p.EndTime == null); foreach (var p in pointers) { p.EventData = evt.EventData; p.EventPublished = true; p.Active = true; } workflow.NextExecution = 0; await _persistenceStore.PersistWorkflow(workflow); await _persistenceStore.TerminateSubscription(sub.Id); return(true); } catch (Exception ex) { Logger.LogError(ex, ex.Message); return(false); } finally { await _lockProvider.ReleaseLock(sub.WorkflowId); await QueueProvider.QueueWork(sub.WorkflowId, QueueType.Workflow); } }
private async Task SubscribeEvent(EventSubscription subscription, IPersistenceProvider persistenceStore, CancellationToken cancellationToken) { //TODO: move to own class Logger.LogDebug("Subscribing to event {0} {1} for workflow {2} step {3}", subscription.EventName, subscription.EventKey, subscription.WorkflowId, subscription.StepId); await persistenceStore.CreateEventSubscription(subscription, cancellationToken); if (subscription.EventName != Event.EventTypeActivity) { var events = await persistenceStore.GetEvents(subscription.EventName, subscription.EventKey, subscription.SubscribeAsOf, cancellationToken); foreach (var evt in events) { var eventKey = $"evt:{evt}"; bool acquiredLock = false; try { acquiredLock = await _lockProvider.AcquireLock(eventKey, cancellationToken); int attempt = 0; while (!acquiredLock && attempt < 10) { await Task.Delay(Options.IdleTime, cancellationToken); acquiredLock = await _lockProvider.AcquireLock(eventKey, cancellationToken); attempt++; } if (!acquiredLock) { Logger.LogWarning($"Failed to lock {evt}"); } else { _greylist.Remove(eventKey); await persistenceStore.MarkEventUnprocessed(evt, cancellationToken); await QueueProvider.QueueWork(evt, QueueType.Event); } } finally { if (acquiredLock) { await _lockProvider.ReleaseLock(eventKey); } } } } }
private async Task SubscribeEvent(EventSubscription subscription, IPersistenceProvider persistenceStore) { //TODO: move to own class Logger.LogDebug("Subscribing to event {0} {1} for workflow {2} step {3}", subscription.EventName, subscription.EventKey, subscription.WorkflowId, subscription.StepId); await persistenceStore.CreateEventSubscription(subscription); var events = await persistenceStore.GetEvents(subscription.EventName, subscription.EventKey, subscription.SubscribeAsOf); foreach (var evt in events) { await persistenceStore.MarkEventUnprocessed(evt); await QueueProvider.QueueWork(evt, QueueType.Event); } }