public async Task <bool> ResumeWorkflow(string workflowId) { if (LockProvider.AcquireLock(workflowId).Result) { bool requeue = false; try { var wf = await PersistenceStore.GetWorkflowInstance(workflowId); if (wf.Status == WorkflowStatus.Suspended) { wf.Status = WorkflowStatus.Runnable; await PersistenceStore.PersistWorkflow(wf); requeue = true; return(true); } return(false); } finally { await LockProvider.ReleaseLock(workflowId); if (requeue) { await QueueProvider.QueueForProcessing(workflowId); } } } return(false); }
/// <summary> /// Worker thread body /// </summary> private void RunWorkflows() { IWorkflowExecutor workflowExecutor = _serviceProvider.GetService <IWorkflowExecutor>(); IPersistenceProvider persistenceStore = _serviceProvider.GetService <IPersistenceProvider>(); while (!_shutdown) { try { var workflowId = QueueProvider.DequeueForProcessing().Result; if (workflowId != null) { try { if (LockProvider.AcquireLock(workflowId).Result) { WorkflowInstance workflow = null; try { workflow = persistenceStore.GetWorkflowInstance(workflowId).Result; if (workflow.Status == WorkflowStatus.Runnable) { workflowExecutor.Execute(workflow, persistenceStore, Options); } } finally { LockProvider.ReleaseLock(workflowId).Wait(); if (workflow != null) { if ((workflow.Status == WorkflowStatus.Runnable) && workflow.NextExecution.HasValue && workflow.NextExecution.Value < DateTime.Now.ToUniversalTime().Ticks) { QueueProvider.QueueForProcessing(workflowId); } } } } else { Logger.LogInformation("Workflow locked {0}", workflowId); } } catch (Exception ex) { Logger.LogError(ex.Message); } } else { Thread.Sleep(Options.IdleTime); //no work } } catch (Exception ex) { Logger.LogError(ex.Message); } } }
/// <summary> /// Poll the persistence store for workflows ready to run. /// Poll the persistence store for stashed unpublished events /// </summary> private void PollRunnables(object target) { try { if (LockProvider.AcquireLock("poll runnables").Result) { try { Logger.LogInformation("Polling for runnable workflows"); IPersistenceProvider persistenceStore = _serviceProvider.GetService <IPersistenceProvider>(); var runnables = persistenceStore.GetRunnableInstances().Result; foreach (var item in runnables) { Logger.LogDebug("Got runnable instance {0}", item); QueueProvider.QueueForProcessing(item); } } finally { LockProvider.ReleaseLock("poll runnables").Wait(); } } } catch (Exception ex) { Logger.LogError(ex.Message); } try { if (LockProvider.AcquireLock("unpublished events").Result) { try { Logger.LogInformation("Polling for unpublished events"); IPersistenceProvider persistenceStore = _serviceProvider.GetService <IPersistenceProvider>(); var events = persistenceStore.GetUnpublishedEvents().Result.ToList(); foreach (var item in events) { Logger.LogDebug("Got unpublished event {0} {1}", item.EventName, item.EventKey); QueueProvider.QueueForPublishing(item).Wait(); persistenceStore.RemoveUnpublishedEvent(item.Id).Wait(); } } finally { LockProvider.ReleaseLock("unpublished events").Wait(); } } } catch (Exception ex) { Logger.LogError(ex.Message); } }
public async Task <string> StartWorkflow <TData>(string workflowId, int?version, TData data = null) where TData : class { if (_shutdown) { throw new Exception("Host is not running"); } var def = Registry.GetDefinition(workflowId, version); if (def == null) { throw new Exception(String.Format("Workflow {0} version {1} is not registered", workflowId, version)); } var wf = new WorkflowInstance(); wf.WorkflowDefinitionId = workflowId; wf.Version = def.Version; wf.Data = data; wf.Description = def.Description; wf.NextExecution = 0; wf.CreateTime = DateTime.Now.ToUniversalTime(); wf.Status = WorkflowStatus.Runnable; if ((def.DataType != null) && (data == null)) { wf.Data = def.DataType.GetConstructor(new Type[] { }).Invoke(null); } wf.ExecutionPointers.Add(new ExecutionPointer() { Id = Guid.NewGuid().ToString(), StepId = def.InitialStep, Active = true, ConcurrentFork = 1, StepName = def.Steps.First(x => x.Id == def.InitialStep).Name }); string id = await PersistenceStore.CreateNewWorkflow(wf); await QueueProvider.QueueForProcessing(id); return(id); }
private void RunPublications() { IPersistenceProvider persistenceStore = _serviceProvider.GetService <IPersistenceProvider>(); while (!_shutdown) { try { var pub = QueueProvider.DequeueForPublishing().Result; if (pub != null) { try { if (LockProvider.AcquireLock(pub.WorkflowId).Result) { try { var workflow = persistenceStore.GetWorkflowInstance(pub.WorkflowId).Result; var pointers = workflow.ExecutionPointers.Where(p => p.EventName == pub.EventName && p.EventKey == p.EventKey && !p.EventPublished); foreach (var p in pointers) { p.EventData = pub.EventData; p.EventPublished = true; p.Active = true; } workflow.NextExecution = 0; persistenceStore.PersistWorkflow(workflow); } catch (Exception ex) { Logger.LogError(ex.Message); persistenceStore.CreateUnpublishedEvent(pub); //retry later } finally { LockProvider.ReleaseLock(pub.WorkflowId).Wait(); QueueProvider.QueueForProcessing(pub.WorkflowId); } } else { Logger.LogInformation("Workflow locked {0}", pub.WorkflowId); persistenceStore.CreateUnpublishedEvent(pub); //retry later } } catch (Exception ex) { Logger.LogError(ex.Message); } } else { Thread.Sleep(Options.IdleTime); //no work } } catch (Exception ex) { Logger.LogError(ex.Message); } } }