public void PredictorShouldSupportLoops() { // Arrange var workplan = WorkplanDummy.WithLoop(); var predictor = Workflow.PathPrediction(workplan); var executor = new SingleLoopExecution(); NodeClassification prediction = NodeClassification.Intermediate; predictor.PathPrediction += (sender, args) => prediction = args.PredictedOutcome; var engine = Workflow.CreateEngine(workplan, new NullContext()); engine.ExecutedWorkflow.Transitions.OfType <DummyTransition>().ForEach(dt => dt.ResultOutput = -1); // Disable automatic execution // Act var finalResult = NodeClassification.Intermediate; engine.Completed += (sender, place) => { finalResult = place.Classification; }; engine.TransitionTriggered += (sender, transition) => ThreadPool.QueueUserWorkItem(executor.ResumeAsync, transition); predictor.Monitor(engine); engine.Start(); // Assert while (finalResult == NodeClassification.Intermediate) { Thread.Sleep(1); // Await completion } Assert.AreEqual(finalResult, prediction, "Predication was incorrect"); }
/// <summary> /// Adds a connector to the workplan. /// </summary> /// <param name="workplan">The workplan.</param> /// <param name="name">The name of the connector.</param> /// <param name="classification">The classification of the connector.</param> /// <returns></returns> public static IConnector AddConnector(this Workplan workplan, string name, NodeClassification classification) { var connector = Workflow.CreateConnector(name, classification); workplan.Add(connector); return(connector); }
public Node AddNodeOrIncrement(string label, int weight = 1, NodeClassification classification = NodeClassification.None) { var newNode = new Node(label, weight, classification); var existingItem = this._nodes.SingleOrDefault(x => x.Label.Equals(newNode.Label) && x.Classification.Equals(newNode.Classification)); if (existingItem != null) { existingItem.Weight += newNode.Weight; return(existingItem); } this._nodes.Add(newNode); return(newNode); }
public void PredictFailureBeforeCompletion() { // Arrange var stopWatch = new Stopwatch(); var workplan = WorkplanDummy.CreateBig(); var predictor = Workflow.PathPrediction(workplan); long predictionTime = long.MaxValue; NodeClassification prediction = NodeClassification.Intermediate; predictor.PathPrediction += (sender, args) => { prediction = args.PredictedOutcome; predictionTime = stopWatch.ElapsedMilliseconds; }; var engine = Workflow.CreateEngine(workplan, new NullContext()); engine.ExecutedWorkflow.Transitions.OfType <DummyTransition>().ForEach(dt => dt.ResultOutput = -1); // Disable automatic execution // Act long completionTime = 0; var finalResult = NodeClassification.Intermediate; engine.Completed += (sender, place) => { completionTime = stopWatch.ElapsedMilliseconds; finalResult = place.Classification; }; engine.TransitionTriggered += (sender, transition) => ThreadPool.QueueUserWorkItem(ResumeAsync, transition); predictor.Monitor(engine); stopWatch.Start(); engine.Start(); // Assert while (finalResult == NodeClassification.Intermediate) { Thread.Sleep(1); // Await completion } stopWatch.Stop(); Assert.Less(predictionTime, completionTime, "Engine was completed before a prediction was published."); Assert.AreEqual(finalResult, prediction, "Predication was incorrect"); }
public void PublishPredictionAfterInterruption() { // Arrange var workplan = WorkplanDummy.CreateBig(); var predictor = Workflow.PathPrediction(workplan); NodeClassification prediction = NodeClassification.Intermediate; predictor.PathPrediction += (sender, args) => prediction = args.PredictedOutcome; // Start and pause engine in var engine = Workflow.CreateEngine(workplan, new NullContext()); var transitions = engine.ExecutedWorkflow.Transitions.OfType <DummyTransition>(); transitions.ForEach(dt => dt.ResultOutput = -1); // Disable automatic execution transitions.First().ResultOutput = 1; // Except for the first one engine.TransitionTriggered += (sender, transition) => { }; engine.Start(); // Act var snapshot = engine.Pause(); // Snapshot of the engine in a sure failure path engine.Dispose(); engine = Workflow.CreateEngine(workplan, new NullContext()); engine.Restore(snapshot); // Restore new engine from the snapshot var finalResult = NodeClassification.Intermediate; engine.Completed += (sender, place) => finalResult = place.Classification; engine.TransitionTriggered += (sender, transition) => ThreadPool.QueueUserWorkItem(ResumeAsync, transition); predictor.Monitor(engine); engine.Start(); // This should resume the engine in a failure path and directly raise the event // Assert while (finalResult == NodeClassification.Intermediate) { Thread.Sleep(1); // Await completion } Assert.AreEqual(finalResult, prediction, "Predication was incorrect"); }
/// <summary> /// Create a named connector instance /// </summary> public static IConnector CreateConnector(string name, NodeClassification classification) { return(new Connector { Name = name, Classification = classification }); }
public Node(string label, int weight, NodeClassification classification = NodeClassification.None){ this.Id = Guid.NewGuid().ToString(); this.Label = label; this.Weight = weight; this.Classification = classification; }
public Node GetNodeByLabel(string label, NodeClassification classification = NodeClassification.None) { return(this._nodes.SingleOrDefault(x => x.Label.Equals(label) && x.Classification.Equals(classification))); }
/// <summary> /// Create a <see cref="PathPredictionEventArgs"/> instance for the predicated outcome of a /// <see cref="IWorkflowEngine"/> with a certain probability /// </summary> public PathPredictionEventArgs(IWorkflowEngine engineInstance, NodeClassification predictedOutcome, double probability) { EngineInstance = engineInstance; PredictedOutcome = predictedOutcome; Probability = probability; }
/// <summary> /// Create a <see cref="PathPredictionEventArgs"/> instance for the predicated outcome of a /// <see cref="IWorkflowEngine"/> with absolute certainty /// </summary> public PathPredictionEventArgs(IWorkflowEngine engineInstance, NodeClassification predictedOutcome) : this(engineInstance, predictedOutcome, 1) { }
public Node(NodeTypes type, NodeClassification classification, Vec2i pos) { this.type = type; this.pos = pos; this.classification = classification; }