/// <summary> /// Processes action provided by the given vertex. /// </summary> /// <param name="vertex">The vertex.</param> /// <param name="executionInfo">The object that stores the information about the execution of the schedule.</param> /// <returns>A value indicating if the execution of the schedule should continue.</returns> public ScheduleExecutionState Process(IScheduleVertex vertex, ScheduleExecutionInfo executionInfo) { var actionVertex = vertex as ExecutingActionVertex; if (actionVertex == null) { Debug.Assert(false, "The vertex is of the incorrect type."); return ScheduleExecutionState.IncorrectProcessorForVertex; } if (executionInfo.Cancellation.IsCancellationRequested) { return ScheduleExecutionState.Canceled; } if (executionInfo.PauseHandler.IsPaused) { executionInfo.PauseHandler.WaitForUnPause(executionInfo.Cancellation); } var id = actionVertex.ActionToExecute; if (!m_Storage.Contains(id)) { throw new UnknownScheduleActionException(); } var action = m_Storage.Action(id); action.Execute(executionInfo.Cancellation); return ScheduleExecutionState.Executing; }
public void ProcessWithIncorrectVertexType() { var processor = new InsertVertexProcessor(); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new StartVertex(1), info); Assert.AreEqual(ScheduleExecutionState.IncorrectProcessorForVertex, state); } }
public void Process() { var processor = new InsertVertexProcessor(); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new InsertVertex(1), info); Assert.AreEqual(ScheduleExecutionState.Executing, state); } }
public void ProcessWithIncorrectVertexType() { var collection = ScheduleActionStorage.CreateInstanceWithoutTimeline(); var processor = new ActionVertexProcessor(collection); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new StartVertex(1), info); Assert.AreEqual(ScheduleExecutionState.IncorrectProcessorForVertex, state); } }
public void ProcessWithIncorrectVertexType() { var timeline = new Mock<ITimeline>(); var processor = new MarkHistoryVertexProcessor(timeline.Object, m => { }); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new StartVertex(1), info); Assert.AreEqual(ScheduleExecutionState.IncorrectProcessorForVertex, state); } }
public void ProcessWithCancellation() { using (var info = new ScheduleExecutionInfo()) { info.CancelScheduleExecution(); var processor = new StartVertexProcessor(); var state = processor.Process(new StartVertex(1), info); Assert.AreEqual(ScheduleExecutionState.Canceled, state); } }
public void ProcessWithIncorrectVertexType() { var timeline = new Mock <ITimeline>(); var processor = new MarkHistoryVertexProcessor(timeline.Object, m => { }); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new StartVertex(1), info); Assert.AreEqual(ScheduleExecutionState.IncorrectProcessorForVertex, state); } }
public void ProcessWithIncorrectVertexType() { var distributor = new Mock <IDistributeScheduleExecutions>(); var processor = new SubScheduleVertexProcessor(distributor.Object); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new StartVertex(1), info); Assert.AreEqual(ScheduleExecutionState.IncorrectProcessorForVertex, state); } }
public void ProcessWithCancellation() { using (var info = new ScheduleExecutionInfo()) { info.CancelScheduleExecution(); var processor = new InsertVertexProcessor(); var state = processor.Process(new InsertVertex(1), info); Assert.AreEqual(ScheduleExecutionState.Canceled, state); } }
/// <summary> /// Processes action provided by the given vertex. /// </summary> /// <param name="vertex">The vertex.</param> /// <param name="executionInfo">The object that stores the information about the execution of the schedule.</param> /// <returns>A value indicating if the execution of the schedule should continue.</returns> public ScheduleExecutionState Process(IScheduleVertex vertex, ScheduleExecutionInfo executionInfo) { var endVertex = vertex as EndVertex; if (endVertex == null) { Debug.Assert(false, "The vertex is of the incorrect type."); return ScheduleExecutionState.IncorrectProcessorForVertex; } // We don't check for pause or cancel here, we're done anyway return ScheduleExecutionState.Completed; }
public void ProcessWithCancellation() { var distributor = new Mock<IDistributeScheduleExecutions>(); using (var info = new ScheduleExecutionInfo()) { info.CancelScheduleExecution(); var processor = new SubScheduleVertexProcessor(distributor.Object); var state = processor.Process(new SubScheduleVertex(1, new ScheduleId()), info); Assert.AreEqual(ScheduleExecutionState.Canceled, state); } }
public void ProcessWithCancellation() { var timeline = new Mock<ITimeline>(); using (var info = new ScheduleExecutionInfo()) { info.CancelScheduleExecution(); var processor = new MarkHistoryVertexProcessor(timeline.Object, m => { }); var state = processor.Process(new MarkHistoryVertex(1), info); Assert.AreEqual(ScheduleExecutionState.Canceled, state); } }
/// <summary> /// Processes action provided by the given vertex. /// </summary> /// <param name="vertex">The vertex.</param> /// <param name="executionInfo">The object that stores the information about the execution of the schedule.</param> /// <returns>A value indicating if the execution of the schedule should continue.</returns> public ScheduleExecutionState Process(IScheduleVertex vertex, ScheduleExecutionInfo executionInfo) { var endVertex = vertex as EndVertex; if (endVertex == null) { Debug.Assert(false, "The vertex is of the incorrect type."); return(ScheduleExecutionState.IncorrectProcessorForVertex); } // We don't check for pause or cancel here, we're done anyway return(ScheduleExecutionState.Completed); }
public void ProcessWithCancellation() { var distributor = new Mock <IDistributeScheduleExecutions>(); using (var info = new ScheduleExecutionInfo()) { info.CancelScheduleExecution(); var processor = new SubScheduleVertexProcessor(distributor.Object); var state = processor.Process(new SubScheduleVertex(1, new ScheduleId()), info); Assert.AreEqual(ScheduleExecutionState.Canceled, state); } }
public void ProcessWithCancellation() { var timeline = new Mock <ITimeline>(); using (var info = new ScheduleExecutionInfo()) { info.CancelScheduleExecution(); var processor = new MarkHistoryVertexProcessor(timeline.Object, m => { }); var state = processor.Process(new MarkHistoryVertex(1), info); Assert.AreEqual(ScheduleExecutionState.Canceled, state); } }
/// <summary> /// Processes action provided by the given vertex. /// </summary> /// <param name="vertex">The vertex.</param> /// <param name="executionInfo">The object that stores the information about the execution of the schedule.</param> /// <returns>A value indicating if the execution of the schedule should continue.</returns> public ScheduleExecutionState Process(IScheduleVertex vertex, ScheduleExecutionInfo executionInfo) { var startVertex = vertex as StartVertex; if (startVertex == null) { Debug.Assert(false, "The vertex is of the incorrect type."); return ScheduleExecutionState.IncorrectProcessorForVertex; } if (executionInfo.Cancellation.IsCancellationRequested) { return ScheduleExecutionState.Canceled; } return ScheduleExecutionState.Executing; }
/// <summary> /// Processes action provided by the given vertex. /// </summary> /// <param name="vertex">The vertex.</param> /// <param name="executionInfo">The object that stores the information about the execution of the schedule.</param> /// <returns>A value indicating if the execution of the schedule should continue.</returns> public ScheduleExecutionState Process(IScheduleVertex vertex, ScheduleExecutionInfo executionInfo) { var startVertex = vertex as StartVertex; if (startVertex == null) { Debug.Assert(false, "The vertex is of the incorrect type."); return(ScheduleExecutionState.IncorrectProcessorForVertex); } if (executionInfo.Cancellation.IsCancellationRequested) { return(ScheduleExecutionState.Canceled); } return(ScheduleExecutionState.Executing); }
public void Process() { var marker = new TimeMarker(10); var timeline = new Mock<ITimeline>(); { timeline.Setup(t => t.Mark()) .Returns(marker); } TimeMarker storedMarker = null; var processor = new MarkHistoryVertexProcessor(timeline.Object, m => storedMarker = m); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new MarkHistoryVertex(1), info); Assert.AreEqual(ScheduleExecutionState.Executing, state); Assert.AreEqual(marker, storedMarker); } }
public void Process() { var marker = new TimeMarker(10); var timeline = new Mock <ITimeline>(); { timeline.Setup(t => t.Mark()) .Returns(marker); } TimeMarker storedMarker = null; var processor = new MarkHistoryVertexProcessor(timeline.Object, m => storedMarker = m); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new MarkHistoryVertex(1), info); Assert.AreEqual(ScheduleExecutionState.Executing, state); Assert.AreEqual(marker, storedMarker); } }
public void Process() { var action = new Mock<IScheduleAction>(); { action.Setup(a => a.Execute(It.IsAny<CancellationToken>())) .Verifiable(); } var collection = ScheduleActionStorage.CreateInstanceWithoutTimeline(); var info = collection.Add( action.Object, "a", "b"); var processor = new ActionVertexProcessor(collection); using (var executionInfo = new ScheduleExecutionInfo()) { var state = processor.Process(new ExecutingActionVertex(1, info.Id), executionInfo); Assert.AreEqual(ScheduleExecutionState.Executing, state); action.Verify(a => a.Execute(It.IsAny<CancellationToken>()), Times.Once()); } }
public void Process() { var action = new Mock <IScheduleAction>(); { action.Setup(a => a.Execute(It.IsAny <CancellationToken>())) .Verifiable(); } var collection = ScheduleActionStorage.CreateInstanceWithoutTimeline(); var info = collection.Add( action.Object, "a", "b"); var processor = new ActionVertexProcessor(collection); using (var executionInfo = new ScheduleExecutionInfo()) { var state = processor.Process(new ExecutingActionVertex(1, info.Id), executionInfo); Assert.AreEqual(ScheduleExecutionState.Executing, state); action.Verify(a => a.Execute(It.IsAny <CancellationToken>()), Times.Once()); } }
public void Process() { var subExecutor = new Mock <IExecuteSchedules>(); { subExecutor.Setup(s => s.IsLocal) .Returns(false); } var distributor = new Mock <IDistributeScheduleExecutions>(); { distributor.Setup( d => d.Execute( It.IsAny <ScheduleId>(), It.IsAny <IEnumerable <IScheduleVariable> >(), It.IsAny <ScheduleExecutionInfo>(), It.IsAny <bool>())) .Returns(subExecutor.Object) .Verifiable(); } var id = new ScheduleId(); var processor = new SubScheduleVertexProcessor(distributor.Object); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new SubScheduleVertex(1, id), info); Assert.AreEqual(ScheduleExecutionState.Executing, state); distributor.Verify( d => d.Execute( It.Is <ScheduleId>(incoming => incoming.Equals(id)), It.IsAny <IEnumerable <IScheduleVariable> >(), It.IsAny <ScheduleExecutionInfo>(), It.IsAny <bool>()), Times.Once()); } }
public void Process() { var subExecutor = new Mock<IExecuteSchedules>(); { subExecutor.Setup(s => s.IsLocal) .Returns(false); } var distributor = new Mock<IDistributeScheduleExecutions>(); { distributor.Setup( d => d.Execute( It.IsAny<ScheduleId>(), It.IsAny<IEnumerable<IScheduleVariable>>(), It.IsAny<ScheduleExecutionInfo>(), It.IsAny<bool>())) .Returns(subExecutor.Object) .Verifiable(); } var id = new ScheduleId(); var processor = new SubScheduleVertexProcessor(distributor.Object); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new SubScheduleVertex(1, id), info); Assert.AreEqual(ScheduleExecutionState.Executing, state); distributor.Verify( d => d.Execute( It.Is<ScheduleId>(incoming => incoming.Equals(id)), It.IsAny<IEnumerable<IScheduleVariable>>(), It.IsAny<ScheduleExecutionInfo>(), It.IsAny<bool>()), Times.Once()); } }
/// <summary> /// Processes action provided by the given vertex. /// </summary> /// <param name="vertex">The vertex.</param> /// <param name="executionInfo">The object that stores the information about the execution of the schedule.</param> /// <returns>A value indicating if the execution of the schedule should continue.</returns> public ScheduleExecutionState Process(IScheduleVertex vertex, ScheduleExecutionInfo executionInfo) { var markVertex = vertex as MarkHistoryVertex; if (markVertex == null) { Debug.Assert(false, "The vertex is of the incorrect type."); return ScheduleExecutionState.IncorrectProcessorForVertex; } if (executionInfo.Cancellation.IsCancellationRequested) { return ScheduleExecutionState.Canceled; } if (executionInfo.PauseHandler.IsPaused) { executionInfo.PauseHandler.WaitForUnPause(executionInfo.Cancellation); } var marker = m_Timeline.Mark(); m_OnMarkerStorage(marker); return ScheduleExecutionState.Executing; }
/// <summary> /// Processes action provided by the given vertex. /// </summary> /// <param name="vertex">The vertex.</param> /// <param name="executionInfo">The object that stores the information about the execution of the schedule.</param> /// <returns>A value indicating if the execution of the schedule should continue.</returns> public ScheduleExecutionState Process(IScheduleVertex vertex, ScheduleExecutionInfo executionInfo) { var subScheduleVertex = vertex as SubScheduleVertex; if (subScheduleVertex == null) { Debug.Assert(false, "The vertex is of the incorrect type."); return(ScheduleExecutionState.IncorrectProcessorForVertex); } if (executionInfo.Cancellation.IsCancellationRequested) { return(ScheduleExecutionState.Canceled); } if (executionInfo.PauseHandler.IsPaused) { executionInfo.PauseHandler.WaitForUnPause(executionInfo.Cancellation); } // And how do we deal with loops? We'll cache the schedule if we're in-process but what about being out-of-process? We'll need to // keep the remote app alive ... // --> We'll need some kind of class that handles making the decision for in-process / out-of-process. // * If it's small then we want to do in-process because the loading of a new dataset takes a while // * If it's a parametrized thing then we might want to do out-of-process because we can run many more in one go // // Determine if we're running the sub-simulation synchronous (in-process) or ascynchronous (out-of-process) // Depends on: // - If the original schedule is allowed to split out sub-schedules out-of-process (when running in interactive mode we may // not allow this) // - 'size' of the sub-schedule // // Determine if we should go out of process here // Going out of process only makes sense if the overhead of going out of process is less than // the overhead of staying in process. // The overhead of going out of process is: // * Serialize all the data we need // * Load an application // * Stream the data across // * Deserialize data // * Re-serialize the data that we need (this may be less than what we send across) // * Send data across // * Deserialize data in original app // The overhead for staying in process is given by the fact that we can only run one schedule // at the time // // So going out of process makes sense when: // * There are multiple sub-schedules before the next sync block // ==> that means we can run all of them in parallel and the sync block indicates when we'll need the data // * We want to run the same sub-schedule with multiple parameters // ==> Run the parameter values all at the same time // * We want to split the current calculation out into multiple bits (domain decomposition type) // // Can we determine this when we build the schedule? // Possibly for some sections? bool executeOutOfProcess = false; IEnumerable <IScheduleVariable> parameters = null; var executor = m_Executor.Execute(subScheduleVertex.ScheduleToExecute, parameters, executionInfo, executeOutOfProcess); // if we're running in-process then we probably have to wait for the sub-schedule to // finish executing because we don't want to have to make the schedule execution thread safe // If it's running out-of-process then we don't bother waiting. There should be a sync block // around this section that will sort out the variable synchronization. if (executor.IsLocal) { var resetEvent = new AutoResetEvent(false); var wrapperWait = Observable.FromEventPattern <ScheduleExecutionStateEventArgs>( h => executor.OnFinish += h, h => executor.OnFinish -= h) .Take(1) .Subscribe(args => resetEvent.Set()); using (wrapperWait) { resetEvent.WaitOne(); } } return(ScheduleExecutionState.Executing); }
public void ProcessWithIncorrectVertexType() { var distributor = new Mock<IDistributeScheduleExecutions>(); var processor = new SubScheduleVertexProcessor(distributor.Object); using (var info = new ScheduleExecutionInfo()) { var state = processor.Process(new StartVertex(1), info); Assert.AreEqual(ScheduleExecutionState.IncorrectProcessorForVertex, state); } }
/// <summary> /// Processes action provided by the given vertex. /// </summary> /// <param name="vertex">The vertex.</param> /// <param name="executionInfo">The object that stores the information about the execution of the schedule.</param> /// <returns>A value indicating if the execution of the schedule should continue.</returns> public ScheduleExecutionState Process(IScheduleVertex vertex, ScheduleExecutionInfo executionInfo) { var subScheduleVertex = vertex as SubScheduleVertex; if (subScheduleVertex == null) { Debug.Assert(false, "The vertex is of the incorrect type."); return ScheduleExecutionState.IncorrectProcessorForVertex; } if (executionInfo.Cancellation.IsCancellationRequested) { return ScheduleExecutionState.Canceled; } if (executionInfo.PauseHandler.IsPaused) { executionInfo.PauseHandler.WaitForUnPause(executionInfo.Cancellation); } // And how do we deal with loops? We'll cache the schedule if we're in-process but what about being out-of-process? We'll need to // keep the remote app alive ... // --> We'll need some kind of class that handles making the decision for in-process / out-of-process. // * If it's small then we want to do in-process because the loading of a new dataset takes a while // * If it's a parametrized thing then we might want to do out-of-process because we can run many more in one go // // Determine if we're running the sub-simulation synchronous (in-process) or ascynchronous (out-of-process) // Depends on: // - If the original schedule is allowed to split out sub-schedules out-of-process (when running in interactive mode we may // not allow this) // - 'size' of the sub-schedule // // Determine if we should go out of process here // Going out of process only makes sense if the overhead of going out of process is less than // the overhead of staying in process. // The overhead of going out of process is: // * Serialize all the data we need // * Load an application // * Stream the data across // * Deserialize data // * Re-serialize the data that we need (this may be less than what we send across) // * Send data across // * Deserialize data in original app // The overhead for staying in process is given by the fact that we can only run one schedule // at the time // // So going out of process makes sense when: // * There are multiple sub-schedules before the next sync block // ==> that means we can run all of them in parallel and the sync block indicates when we'll need the data // * We want to run the same sub-schedule with multiple parameters // ==> Run the parameter values all at the same time // * We want to split the current calculation out into multiple bits (domain decomposition type) // // Can we determine this when we build the schedule? // Possibly for some sections? bool executeOutOfProcess = false; IEnumerable<IScheduleVariable> parameters = null; var executor = m_Executor.Execute(subScheduleVertex.ScheduleToExecute, parameters, executionInfo, executeOutOfProcess); // if we're running in-process then we probably have to wait for the sub-schedule to // finish executing because we don't want to have to make the schedule execution thread safe // If it's running out-of-process then we don't bother waiting. There should be a sync block // around this section that will sort out the variable synchronization. if (executor.IsLocal) { var resetEvent = new AutoResetEvent(false); var wrapperWait = Observable.FromEventPattern<ScheduleExecutionStateEventArgs>( h => executor.OnFinish += h, h => executor.OnFinish -= h) .Take(1) .Subscribe(args => resetEvent.Set()); using (wrapperWait) { resetEvent.WaitOne(); } } return ScheduleExecutionState.Executing; }