public void Execute(IExecution execution) { execution.Stop(); int incomingTransitionCount = execution.CurrentNode.IncomingTransitions.Count(); if (incomingTransitionCount > 1) { var root = execution.GetConcurrentRoot(); var executionCollector = new ExecutionCollector(e => !e.IsActive && e.CurrentNode == execution.CurrentNode); root.Accept(executionCollector); int joinedTransitionCount = executionCollector.Result.DistinctBy(e => e.IncomingTransition).Count(); if (incomingTransitionCount > joinedTransitionCount) { Logger.InfoFormat("Cannot join in node '{0}' yet. Joined: {1}, To join: {2}. Waiting...", execution.CurrentNode.Identifier, joinedTransitionCount, incomingTransitionCount); execution.Wait(); return; } root.Split(execution.CurrentNode); } else { execution.Split(execution.CurrentNode); } }
public IExecution LoadExecution(string executionIdentifier, IExecutionPlan executionPlan) { var rootQuery = graphClient.Cypher .Match("(e:Execution {Identifier: {id}})") .OptionalMatch("(r:Execution)-[:PARENT_OF*]->(e)") .OptionalMatch("(r)-[:EXECUTES]->(currentNode:Node)") .Where("NOT (:Execution)-[:PARENT_OF*]->(r)") .WithParam("id", executionIdentifier) .Return((r, e, currentNode) => new { Root = r.As<ExecutionModel>(), Current = e.As<ExecutionModel>(), CurrentNode = currentNode.As<NodeModel>() }); var executionModel = rootQuery.Results.Last(); var root = executionModel.Root ?? executionModel.Current; var wfQuery = graphClient.Cypher .Match("(e:Execution {Identifier: {id}})-[*]->(n:Node)") .Match("(wf:WorkflowDefinition)-[*]->(n)") .OptionalMatch( "(e:Execution {Identifier: {id}})-[:REFERENCES]->(wf:WorkflowDefinition)") .WithParam("id", root.Identifier) .Return(wf => wf.As<WorkflowDefinitionModel>()); var workflowDefinition = LoadWorkflowDefinition(wfQuery.Results.First().Identifier); Dictionary<string, object> data = (Dictionary<string, object>) objectSerializer.Deserialize(root.Data, typeof (Dictionary<string, object>)); var children = new List<IExecution>(); var rootExecution = new Execution(null, executionModel.CurrentNode == null ? null : workflowDefinition.Nodes.First(n => n.Identifier == executionModel.CurrentNode.Identifier), root.IsActive, root.IsFinished, data, root.IncomingTransition, root.Identifier, root.WorkflowInstanceIdentifier, executionPlan, children, workflowDefinition); FillChildren(rootExecution, children, executionPlan, workflowDefinition); var collector = new ExecutionCollector(e => e.Identifier == executionIdentifier); rootExecution.Accept(collector); return collector.Result.First(); }
public IExecution TransformBack(ExecutionModel model, IWorkflowDefinition workflowDefinition, IExecutionPlan plan) { if (model == null) { return null; } var root = FindRoot(model); var transformedRoot = TransformBack(root, plan, workflowDefinition, null); var collector = new ExecutionCollector(e => e.Identifier == model.Identifier); transformedRoot.Accept(collector); return collector.Result.First(); }