Esempio n. 1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ScheduleExecutionInfo"/> class.
 /// </summary>
 /// <param name="parent">The information object for the parent schedule.</param>
 public ScheduleExecutionInfo(ScheduleExecutionInfo parent)
     : this()
 {
     m_Parent = parent;
     if (m_Parent != null)
     {
         m_CombinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(
             m_Parent.Cancellation,
             m_LocalCancellationSource.Token);
     }
 }
Esempio n. 2
0
        public void RunWithSubScheduleVertex()
        {
            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);
            }

            var id       = new ScheduleId();
            var schedule = BuildThreeVertexSchedule(new SubScheduleVertex(3, id));

            using (var info = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                           new List <IProcesExecutableScheduleVertices>
                {
                    new StartVertexProcessor(),
                    new EndVertexProcessor(),
                    new SubScheduleVertexProcessor(distributor.Object),
                },
                           ScheduleConditionStorage.CreateInstanceWithoutTimeline(),
                           schedule,
                           new ScheduleId(),
                           info))
                {
                    var state = ScheduleExecutionState.None;
                    executor.OnFinish += (s, e) => { state = e.State; };

                    executor.Start();
                    Assert.AreEqual(ScheduleExecutionState.Completed, state);
                }
            }
        }
Esempio n. 3
0
        private IExecuteSchedules ExecuteInProcess(
            ScheduleId scheduleId,
            IEnumerable <IScheduleVariable> scheduleParameters,
            ScheduleExecutionInfo executionInfo)
        {
            // Translate the schedule to an executable schedule
            var editableSchedule = m_KnownSchedules.Schedule(scheduleId);

            // Create a new executor and provide it with the schedule
            var executor = m_LoadExecutor(editableSchedule, scheduleId, executionInfo);

            {
                // Attach to events. We want to remove the executor from the collection as soon as it's finished
                executor.OnFinish += HandleScheduleExecutionFinish;
                m_RunningExecutors.Add(new ExecutingScheduleKey(scheduleId, scheduleParameters), executor);

                executor.Start(scheduleParameters);
            }

            return(executor);
        }
Esempio n. 4
0
        public void RunWithActionVertex()
        {
            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 schedule = BuildThreeVertexSchedule(new ExecutingActionVertex(3, info.Id));

            using (var executionInfo = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                           new List <IProcesExecutableScheduleVertices>
                {
                    new StartVertexProcessor(),
                    new EndVertexProcessor(),
                    new ActionVertexProcessor(collection),
                },
                           ScheduleConditionStorage.CreateInstanceWithoutTimeline(),
                           schedule,
                           new ScheduleId(),
                           executionInfo))
                {
                    var state = ScheduleExecutionState.None;
                    executor.OnFinish += (s, e) => { state = e.State; };

                    executor.Start();
                    Assert.AreEqual(ScheduleExecutionState.Completed, state);
                    action.Verify(a => a.Execute(It.IsAny <CancellationToken>()), Times.Once());
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Determines the most suitable execution location for the given schedule and then starts the execution in that location.
        /// </summary>
        /// <param name="scheduleId">The ID of the schedule that should be executed.</param>
        /// <param name="scheduleParameters">The collection of parameters that have to be provided to the schedule before executing.</param>
        /// <param name="executionInfo">The object that provides information about the schedule that is currently being executed.</param>
        /// <param name="executeOutOfProcess">A flag indicating if the schedule should be executed in another processor or not.</param>
        /// <returns>
        /// The token that is related to the execution of the given schedule.
        /// </returns>
        /// <remarks>
        /// For local schedules the cancellation token is checked regularly and the schedule execution is cancelled on request. For
        /// remote schedule execution setting the cancellation token means that a termination signal is send to the remote
        /// application.
        /// </remarks>
        public IExecuteSchedules Execute(
            ScheduleId scheduleId,
            IEnumerable <IScheduleVariable> scheduleParameters = null,
            ScheduleExecutionInfo executionInfo = null,
            bool executeOutOfProcess            = false)
        {
            lock (m_Lock)
            {
                if (!m_KnownSchedules.Contains(scheduleId))
                {
                    throw new UnknownScheduleException();
                }

                var key = new ExecutingScheduleKey(scheduleId, scheduleParameters);
                if (m_RunningExecutors.ContainsKey(key))
                {
                    return(m_RunningExecutors[key]);
                }

                if (executeOutOfProcess)
                {
                    // Determine what data needs to be serialized for schedule to execute
                    // Serialize all data + components + schedules
                    // Start external app
                    // Feed data stream of data + components + schedules
                    // Indicate which schedule should be executed + parameters
                    // Start
                    // Return distributed schedule executor
                    // --> This is all based on a set of components that can handle all kinds of distribution methods / desires
                    //     For instance we eventually also want to do Domain Decomp this way.
                    throw new NotImplementedException();
                }
                else
                {
                    return(ExecuteInProcess(scheduleId, scheduleParameters, executionInfo));
                }
            }
        }
        public void RunWithActionVertex()
        {
            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 schedule = BuildThreeVertexSchedule(new ExecutingActionVertex(3, info.Id));
            using (var executionInfo = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                    new List<IProcesExecutableScheduleVertices>
                        {
                            new StartVertexProcessor(),
                            new EndVertexProcessor(),
                            new ActionVertexProcessor(collection),
                        },
                    ScheduleConditionStorage.CreateInstanceWithoutTimeline(),
                    schedule,
                    new ScheduleId(),
                    executionInfo))
                {
                    var state = ScheduleExecutionState.None;
                    executor.OnFinish += (s, e) => { state = e.State; };

                    executor.Start();
                    Assert.AreEqual(ScheduleExecutionState.Completed, state);
                    action.Verify(a => a.Execute(It.IsAny<CancellationToken>()), Times.Once());
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ScheduleExecutor"/> class.
        /// </summary>
        /// <param name="executors">The collection of vertex processors.</param>
        /// <param name="conditions">The collection of execution conditions.</param>
        /// <param name="schedule">The schedule that should be executed.</param>
        /// <param name="id">The ID of the schedule that is being executed.</param>
        /// <param name="executionInfo">The object that stores information about the current running schedule.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="executors"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="conditions"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="CannotExecuteScheduleWithoutProcessorsException">
        ///     Thrown if <paramref name="executors"/> is an empty collection.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="schedule"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="id"/> is <see langword="null" />.
        /// </exception>
        public ScheduleExecutor(
            IEnumerable <IProcesExecutableScheduleVertices> executors,
            IStoreScheduleConditions conditions,
            ISchedule schedule,
            ScheduleId id,
            ScheduleExecutionInfo executionInfo = null)
        {
            {
                Lokad.Enforce.Argument(() => executors);
                Lokad.Enforce.With <CannotExecuteScheduleWithoutProcessorsException>(
                    executors.Any(),
                    Resources.Exceptions_Messages_CannotExecuteScheduleWithoutProcessors);

                Lokad.Enforce.Argument(() => conditions);
                Lokad.Enforce.Argument(() => schedule);
                Lokad.Enforce.Argument(() => id);
            }

            m_Executors     = executors.ToDictionary(v => v.VertexTypeToProcess, v => v);
            m_Conditions    = conditions;
            m_Schedule      = schedule;
            m_ScheduleId    = id;
            m_ExecutionInfo = new ScheduleExecutionInfo(executionInfo);
        }
        public void RunWithBlockingConditionOnFirstEdge()
        {
            var condition = new Mock<IScheduleCondition>();
            {
                condition.Setup(c => c.CanTraverse(It.IsAny<CancellationToken>()))
                    .Returns(false);
            }

            var conditionStorage = ScheduleConditionStorage.CreateInstanceWithoutTimeline();
            var conditionInfo = conditionStorage.Add(condition.Object, "a", "b");

            Schedule schedule;
            {
                var graph = new BidirectionalGraph<IScheduleVertex, ScheduleEdge>();
                var start = new StartVertex(1);
                graph.AddVertex(start);

                var end = new EndVertex(2);
                graph.AddVertex(end);

                var middle1 = new InsertVertex(3);
                graph.AddVertex(middle1);

                var middle2 = new InsertVertex(4);
                graph.AddVertex(middle2);

                graph.AddEdge(new ScheduleEdge(start, middle1, conditionInfo.Id));
                graph.AddEdge(new ScheduleEdge(start, middle2));

                graph.AddEdge(new ScheduleEdge(middle1, end));
                graph.AddEdge(new ScheduleEdge(middle2, end));

                schedule = new Schedule(graph, start, end);
            }

            using (var info = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                    new List<IProcesExecutableScheduleVertices>
                        {
                            new StartVertexProcessor(),
                            new EndVertexProcessor(),
                            new InsertVertexProcessor(),
                        },
                    conditionStorage,
                    schedule,
                    new ScheduleId(),
                    info))
                {
                    var executionOrder = new List<int>();
                    executor.OnVertexProcess += (s, e) => executionOrder.Add(e.Vertex);

                    executor.Start();
                    Assert.That(executionOrder, Is.EquivalentTo(new[] { 1, 4, 2 }));
                }
            }
        }
        public void RunWithSubScheduleVertex()
        {
            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);
            }

            var id = new ScheduleId();
            var schedule = BuildThreeVertexSchedule(new SubScheduleVertex(3, id));
            using (var info = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                    new List<IProcesExecutableScheduleVertices>
                        {
                            new StartVertexProcessor(),
                            new EndVertexProcessor(),
                            new SubScheduleVertexProcessor(distributor.Object),
                        },
                    ScheduleConditionStorage.CreateInstanceWithoutTimeline(),
                    schedule,
                    new ScheduleId(),
                    info))
                {
                    var state = ScheduleExecutionState.None;
                    executor.OnFinish += (s, e) => { state = e.State; };

                    executor.Start();
                    Assert.AreEqual(ScheduleExecutionState.Completed, state);
                }
            }
        }
Esempio n. 10
0
        public void RunWithNoOpVertex()
        {
            var schedule = BuildThreeVertexSchedule(new InsertVertex(3));
            using (var info = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                    new List<IProcesExecutableScheduleVertices>
                        {
                            new StartVertexProcessor(),
                            new EndVertexProcessor(),
                            new InsertVertexProcessor(),
                        },
                    ScheduleConditionStorage.CreateInstanceWithoutTimeline(),
                    schedule,
                    new ScheduleId(),
                    info))
                {
                    var state = ScheduleExecutionState.None;
                    executor.OnFinish += (s, e) => { state = e.State; };

                    executor.Start();
                    Assert.AreEqual(ScheduleExecutionState.Completed, state);
                }
            }
        }
Esempio n. 11
0
        public void RunWithNonPassableEdgeSet()
        {
            var condition = new Mock<IScheduleCondition>();
            {
                condition.Setup(c => c.CanTraverse(It.IsAny<CancellationToken>()))
                    .Returns(false);
            }

            var conditionStorage = ScheduleConditionStorage.CreateInstanceWithoutTimeline();
            var conditionInfo = conditionStorage.Add(condition.Object, "a", "b");

            Schedule schedule;
            {
                var graph = new BidirectionalGraph<IScheduleVertex, ScheduleEdge>();
                var start = new StartVertex(1);
                graph.AddVertex(start);

                var end = new EndVertex(2);
                graph.AddVertex(end);

                var middle1 = new InsertVertex(3);
                graph.AddVertex(middle1);

                var middle2 = new InsertVertex(4);
                graph.AddVertex(middle2);

                graph.AddEdge(new ScheduleEdge(start, middle1, conditionInfo.Id));
                graph.AddEdge(new ScheduleEdge(start, middle2, conditionInfo.Id));

                graph.AddEdge(new ScheduleEdge(middle1, end));
                graph.AddEdge(new ScheduleEdge(middle2, end));

                schedule = new Schedule(graph, start, end);
            }

            using (var info = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                    new List<IProcesExecutableScheduleVertices>
                    {
                        new StartVertexProcessor(),
                        new EndVertexProcessor(),
                        new InsertVertexProcessor(),
                    },
                    conditionStorage,
                    schedule,
                    new ScheduleId(),
                    info))
                {
                    var state = ScheduleExecutionState.None;
                    executor.OnFinish += (s, e) => { state = e.State; };

                    executor.Start();
                    Assert.AreEqual(ScheduleExecutionState.NoTraversableEdgeFound, state);
                }
            }
        }
Esempio n. 12
0
        public void RunWithMarkHistoryVertex()
        {
            var marker = new TimeMarker(10);
            var timeline = new Mock<ITimeline>();
            {
                timeline.Setup(t => t.Mark())
                    .Returns(marker);
            }

            TimeMarker storedMarker = null;
            var schedule = BuildThreeVertexSchedule(new MarkHistoryVertex(3));
            using (var info = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                    new List<IProcesExecutableScheduleVertices>
                        {
                            new StartVertexProcessor(),
                            new EndVertexProcessor(),
                            new MarkHistoryVertexProcessor(timeline.Object, m => storedMarker = m),
                        },
                    ScheduleConditionStorage.CreateInstanceWithoutTimeline(),
                    schedule,
                    new ScheduleId(),
                    info))
                {
                    var state = ScheduleExecutionState.None;
                    executor.OnFinish += (s, e) => { state = e.State; };

                    executor.Start();
                    Assert.AreEqual(ScheduleExecutionState.Completed, state);
                    Assert.AreEqual(marker, storedMarker);
                }
            }
        }
Esempio n. 13
0
        public void RunWithLoop()
        {
            bool passThrough = false;
            var condition = new Mock<IScheduleCondition>();
            {
                condition.Setup(c => c.CanTraverse(It.IsAny<CancellationToken>()))
                    .Returns(() => passThrough);
            }

            var conditionStorage = ScheduleConditionStorage.CreateInstanceWithoutTimeline();
            var conditionInfo = conditionStorage.Add(condition.Object, "a", "b");

            var action = new Mock<IScheduleAction>();
            {
                action.Setup(a => a.Execute(It.IsAny<CancellationToken>()))
                    .Callback(() => passThrough = true);
            }

            var collection = ScheduleActionStorage.CreateInstanceWithoutTimeline();
            var info = collection.Add(
                action.Object,
                "a",
                "b");

            // Making a schedule that looks like:
            // start -> node1 --> node2 -> end
            //            ^           |
            //            |-- node3 <-|
            Schedule schedule;
            {
                var graph = new BidirectionalGraph<IScheduleVertex, ScheduleEdge>();
                var start = new StartVertex(1);
                graph.AddVertex(start);

                var end = new EndVertex(2);
                graph.AddVertex(end);

                var vertex1 = new InsertVertex(3);
                graph.AddVertex(vertex1);

                var vertex2 = new InsertVertex(4);
                graph.AddVertex(vertex2);

                var vertex3 = new ExecutingActionVertex(5, info.Id);
                graph.AddVertex(vertex3);

                graph.AddEdge(new ScheduleEdge(start, vertex1));
                graph.AddEdge(new ScheduleEdge(vertex1, vertex2));

                graph.AddEdge(new ScheduleEdge(vertex2, end, conditionInfo.Id));
                graph.AddEdge(new ScheduleEdge(vertex2, vertex3));

                graph.AddEdge(new ScheduleEdge(vertex3, vertex1));

                schedule = new Schedule(graph, start, end);
            }

            using (var executionInfo = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                    new List<IProcesExecutableScheduleVertices>
                        {
                            new StartVertexProcessor(),
                            new EndVertexProcessor(),
                            new InsertVertexProcessor(),
                            new ActionVertexProcessor(collection),
                        },
                    conditionStorage,
                    schedule,
                    new ScheduleId(),
                    executionInfo))
                {
                    var executionOrder = new List<int>();
                    executor.OnVertexProcess += (s, e) => executionOrder.Add(e.Vertex);

                    executor.Start();
                    Assert.That(executionOrder, Is.EquivalentTo(new[] { 1, 3, 4, 5, 3, 4, 2 }));
                }
            }
        }
Esempio n. 14
0
        public void RunWithInnerAndOuterLoop()
        {
            bool outerLoopPassThrough = false;
            var outerLoopCondition = new Mock<IScheduleCondition>();
            {
                outerLoopCondition.Setup(c => c.CanTraverse(It.IsAny<CancellationToken>()))
                    .Returns(() => outerLoopPassThrough);
            }

            bool innerLoopPassThrough = false;
            var innerLoopCondition = new Mock<IScheduleCondition>();
            {
                innerLoopCondition.Setup(c => c.CanTraverse(It.IsAny<CancellationToken>()))
                    .Returns(() => innerLoopPassThrough);
            }

            var conditionStorage = ScheduleConditionStorage.CreateInstanceWithoutTimeline();
            var outerLoopConditionInfo = conditionStorage.Add(
                outerLoopCondition.Object,
                "a",
                "b");
            var innerLoopConditionInfo = conditionStorage.Add(
                innerLoopCondition.Object,
                "a",
                "b");

            var outerLoopAction = new Mock<IScheduleAction>();
            {
                outerLoopAction.Setup(a => a.Execute(It.IsAny<CancellationToken>()))
                    .Callback(() => outerLoopPassThrough = true);
            }

            var innerLoopAction = new Mock<IScheduleAction>();
            {
                innerLoopAction.Setup(a => a.Execute(It.IsAny<CancellationToken>()))
                    .Callback(() => innerLoopPassThrough = true);
            }

            var collection = ScheduleActionStorage.CreateInstanceWithoutTimeline();
            var outerLoopInfo = collection.Add(
                outerLoopAction.Object,
                "a",
                "b");
            var innerLoopInfo = collection.Add(
                innerLoopAction.Object,
                "a",
                "b");

            // Making a schedule that looks like:
            // start -> node1 --> node2 -> end
            //            ^           |
            //            |-- node3 <-|
            //                ^  |
            //         node5--|  |->  node4
            //           ^              |
            //           |--------------|
            Schedule schedule;
            {
                schedule = CreateScheduleGraphWithOuterAndInnerLoop(outerLoopConditionInfo, innerLoopConditionInfo, outerLoopInfo, innerLoopInfo);
            }

            using (var info = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                    new List<IProcesExecutableScheduleVertices>
                    {
                        new StartVertexProcessor(),
                        new EndVertexProcessor(),
                        new InsertVertexProcessor(),
                        new ActionVertexProcessor(collection),
                    },
                    conditionStorage,
                    schedule,
                    new ScheduleId(),
                    info))
                {
                    var executionOrder = new List<int>();
                    executor.OnVertexProcess += (s, e) => executionOrder.Add(e.Vertex);

                    executor.Start();
                    Assert.That(executionOrder, Is.EquivalentTo(new[] { 1, 3, 4, 5, 6, 7, 5, 3, 4, 2 }));
                }
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ScheduleExecutor"/> class.
        /// </summary>
        /// <param name="executors">The collection of vertex processors.</param>
        /// <param name="conditions">The collection of execution conditions.</param>
        /// <param name="schedule">The schedule that should be executed.</param>
        /// <param name="id">The ID of the schedule that is being executed.</param>
        /// <param name="executionInfo">The object that stores information about the current running schedule.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="executors"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="conditions"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="CannotExecuteScheduleWithoutProcessorsException">
        ///     Thrown if <paramref name="executors"/> is an empty collection.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="schedule"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="id"/> is <see langword="null" />.
        /// </exception>
        public ScheduleExecutor(
            IEnumerable<IProcesExecutableScheduleVertices> executors,
            IStoreScheduleConditions conditions,
            ISchedule schedule,
            ScheduleId id,
            ScheduleExecutionInfo executionInfo = null)
        {
            {
                Lokad.Enforce.Argument(() => executors);
                Lokad.Enforce.With<CannotExecuteScheduleWithoutProcessorsException>(
                    executors.Any(),
                    Resources.Exceptions_Messages_CannotExecuteScheduleWithoutProcessors);

                Lokad.Enforce.Argument(() => conditions);
                Lokad.Enforce.Argument(() => schedule);
                Lokad.Enforce.Argument(() => id);
            }

            m_Executors = executors.ToDictionary(v => v.VertexTypeToProcess, v => v);
            m_Conditions = conditions;
            m_Schedule = schedule;
            m_ScheduleId = id;
            m_ExecutionInfo = new ScheduleExecutionInfo(executionInfo);
        }
Esempio n. 16
0
        public void RunWithLoop()
        {
            bool passThrough = false;
            var  condition   = new Mock <IScheduleCondition>();
            {
                condition.Setup(c => c.CanTraverse(It.IsAny <CancellationToken>()))
                .Returns(() => passThrough);
            }

            var conditionStorage = ScheduleConditionStorage.CreateInstanceWithoutTimeline();
            var conditionInfo    = conditionStorage.Add(condition.Object, "a", "b");

            var action = new Mock <IScheduleAction>();
            {
                action.Setup(a => a.Execute(It.IsAny <CancellationToken>()))
                .Callback(() => passThrough = true);
            }

            var collection = ScheduleActionStorage.CreateInstanceWithoutTimeline();
            var info       = collection.Add(
                action.Object,
                "a",
                "b");

            // Making a schedule that looks like:
            // start -> node1 --> node2 -> end
            //            ^           |
            //            |-- node3 <-|
            Schedule schedule;

            {
                var graph = new BidirectionalGraph <IScheduleVertex, ScheduleEdge>();
                var start = new StartVertex(1);
                graph.AddVertex(start);

                var end = new EndVertex(2);
                graph.AddVertex(end);

                var vertex1 = new InsertVertex(3);
                graph.AddVertex(vertex1);

                var vertex2 = new InsertVertex(4);
                graph.AddVertex(vertex2);

                var vertex3 = new ExecutingActionVertex(5, info.Id);
                graph.AddVertex(vertex3);

                graph.AddEdge(new ScheduleEdge(start, vertex1));
                graph.AddEdge(new ScheduleEdge(vertex1, vertex2));

                graph.AddEdge(new ScheduleEdge(vertex2, end, conditionInfo.Id));
                graph.AddEdge(new ScheduleEdge(vertex2, vertex3));

                graph.AddEdge(new ScheduleEdge(vertex3, vertex1));

                schedule = new Schedule(graph, start, end);
            }

            using (var executionInfo = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                           new List <IProcesExecutableScheduleVertices>
                {
                    new StartVertexProcessor(),
                    new EndVertexProcessor(),
                    new InsertVertexProcessor(),
                    new ActionVertexProcessor(collection),
                },
                           conditionStorage,
                           schedule,
                           new ScheduleId(),
                           executionInfo))
                {
                    var executionOrder = new List <int>();
                    executor.OnVertexProcess += (s, e) => executionOrder.Add(e.Vertex);

                    executor.Start();
                    Assert.That(executionOrder, Is.EquivalentTo(new[] { 1, 3, 4, 5, 3, 4, 2 }));
                }
            }
        }
Esempio n. 17
0
        public void RunWithInnerAndOuterLoop()
        {
            bool outerLoopPassThrough = false;
            var  outerLoopCondition   = new Mock <IScheduleCondition>();
            {
                outerLoopCondition.Setup(c => c.CanTraverse(It.IsAny <CancellationToken>()))
                .Returns(() => outerLoopPassThrough);
            }

            bool innerLoopPassThrough = false;
            var  innerLoopCondition   = new Mock <IScheduleCondition>();
            {
                innerLoopCondition.Setup(c => c.CanTraverse(It.IsAny <CancellationToken>()))
                .Returns(() => innerLoopPassThrough);
            }

            var conditionStorage       = ScheduleConditionStorage.CreateInstanceWithoutTimeline();
            var outerLoopConditionInfo = conditionStorage.Add(
                outerLoopCondition.Object,
                "a",
                "b");
            var innerLoopConditionInfo = conditionStorage.Add(
                innerLoopCondition.Object,
                "a",
                "b");

            var outerLoopAction = new Mock <IScheduleAction>();
            {
                outerLoopAction.Setup(a => a.Execute(It.IsAny <CancellationToken>()))
                .Callback(() => outerLoopPassThrough = true);
            }

            var innerLoopAction = new Mock <IScheduleAction>();
            {
                innerLoopAction.Setup(a => a.Execute(It.IsAny <CancellationToken>()))
                .Callback(() => innerLoopPassThrough = true);
            }

            var collection    = ScheduleActionStorage.CreateInstanceWithoutTimeline();
            var outerLoopInfo = collection.Add(
                outerLoopAction.Object,
                "a",
                "b");
            var innerLoopInfo = collection.Add(
                innerLoopAction.Object,
                "a",
                "b");

            // Making a schedule that looks like:
            // start -> node1 --> node2 -> end
            //            ^           |
            //            |-- node3 <-|
            //                ^  |
            //         node5--|  |->  node4
            //           ^              |
            //           |--------------|
            Schedule schedule;

            {
                schedule = CreateScheduleGraphWithOuterAndInnerLoop(outerLoopConditionInfo, innerLoopConditionInfo, outerLoopInfo, innerLoopInfo);
            }

            using (var info = new ScheduleExecutionInfo(new CurrentThreadTaskScheduler()))
            {
                using (var executor = new ScheduleExecutor(
                           new List <IProcesExecutableScheduleVertices>
                {
                    new StartVertexProcessor(),
                    new EndVertexProcessor(),
                    new InsertVertexProcessor(),
                    new ActionVertexProcessor(collection),
                },
                           conditionStorage,
                           schedule,
                           new ScheduleId(),
                           info))
                {
                    var executionOrder = new List <int>();
                    executor.OnVertexProcess += (s, e) => executionOrder.Add(e.Vertex);

                    executor.Start();
                    Assert.That(executionOrder, Is.EquivalentTo(new[] { 1, 3, 4, 5, 6, 7, 5, 3, 4, 2 }));
                }
            }
        }
Esempio n. 18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ScheduleExecutionInfo"/> class.
 /// </summary>
 /// <param name="parent">The information object for the parent schedule.</param>
 public ScheduleExecutionInfo(ScheduleExecutionInfo parent)
     : this()
 {
     m_Parent = parent;
     if (m_Parent != null)
     {
         m_CombinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(
             m_Parent.Cancellation,
             m_LocalCancellationSource.Token);
     }
 }