Пример #1
0
        public void TestSerialPipelineExecution()
        {
            // set SetUp two engines, one with a locked cache progress/load schedule
            // run the serial execution and ensure that only one engine had its 'ExecutePipeline' method called
            var engine1 = new Mock <IDataFlowPipelineEngine>();


            var engine2 = new Mock <IDataFlowPipelineEngine>();

            var tokenSource = new GracefulCancellationTokenSource();
            var listener    = new ThrowImmediatelyDataLoadEventListener();

            // set SetUp the engine map
            var loadProgress1 = Mock.Of <ILoadProgress>();
            var loadProgress2 = Mock.Of <ILoadProgress>();

            // set SetUp the lock provider
            var engineMap = new Dictionary <IDataFlowPipelineEngine, ILoadProgress>
            {
                { engine1.Object, loadProgress1 },
                { engine2.Object, loadProgress2 }
            };

            // create the execution object
            var pipelineExecutor = new SerialPipelineExecution();

            // Act
            pipelineExecutor.Execute(new [] { engine1.Object, engine2.Object }, tokenSource.Token, listener);

            // engine1 should have been executed once
            engine1.Verify(e => e.ExecutePipeline(It.IsAny <GracefulCancellationToken>()), Times.Once);

            // engine2 should also have been run (locking isn't a thing anymore)
            engine2.Verify(e => e.ExecutePipeline(It.IsAny <GracefulCancellationToken>()), Times.Once);
        }
Пример #2
0
        private void BtnRun_Clicked()
        {
            if (cancellation != null)
            {
                MessageBox.ErrorQuery("Already Running", "Pipeline is already running", "Ok");
                return;
            }

            runner = new PipelineRunner(_useCase, _pipeline);
            foreach (var l in additionals)
            {
                runner.AdditionalListeners.Add(l);
            }
            runner.PipelineExecutionFinishedsuccessfully += Runner_PipelineExecutionFinishedsuccessfully;

            // clear old results
            _results.Text         = "";
            _results.SelectedItem = 0;
            Task.Run(() =>
            {
                try
                {
                    cancellation = new GracefulCancellationTokenSource();
                    exitCode     = runner.Run(activator.RepositoryLocator, this, new FromDataLoadEventListenerToCheckNotifier(this), cancellation.Token);
                    cancellation = null;
                }
                catch (Exception ex)
                {
                    OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, ex.Message, ex));
                    cancellation = null;
                }
            });
        }
Пример #3
0
        private void btnExecute_Click(object sender, EventArgs e)
        {
            _cancellationTokenSource = new GracefulCancellationTokenSource();

            IRunner runner;

            try
            {
                var command = CommandGetter(CommandLineActivity.run);
                runner = _factory.CreateRunner(Activator, command);
            }
            catch (Exception ex)
            {
                ragChecks.Fatal(ex);
                return;
            }
            CurrentRunner = runner;

            loadProgressUI1.Clear();
            loadProgressUI1.ShowRunning(true);

            int exitCode = 0;

            _runningTask =
                //run the data load in a Thread
                Task.Factory.StartNew(() => { exitCode = Run(runner); });

            _runningTask
            //then on the main UI thread (after load completes with success/error
            .ContinueWith((t) =>
            {
                //reset the system state because the execution has completed
                ChecksPassed = false;

                loadProgressUI1.ShowRunning(false);

                if (exitCode != 0)
                {
                    loadProgressUI1.SetFatal();
                }

                if (ExecutionFinished != null)
                {
                    ExecutionFinished(this, new ExecutionEventArgs(exitCode));
                }

                //adjust the buttons accordingly
                SetButtonStates();
            }
                          , TaskScheduler.FromCurrentSynchronizationContext());

            SetButtonStates();
        }
Пример #4
0
        public void LoadNotRequiredStopsPipelineGracefully()
        {
            var component = new NotRequiredComponent();

            var pipeline = new SingleJobExecution(new List <IDataLoadComponent> {
                component
            });

            var job            = Mock.Of <IDataLoadJob>();
            var jobTokenSource = new GracefulCancellationTokenSource();

            pipeline.Run(job, jobTokenSource.Token);
        }
Пример #5
0
        public void ColumnDropper_NoMatchingColumnAtRuntime()
        {
            var dropper = new ColumnDropper
            {
                ColumnNameToDrop = "DoesNotExist"
            };

            var cts       = new GracefulCancellationTokenSource();
            var toProcess = new DataTable();

            toProcess.Columns.Add("Column1");

            var ex = Assert.Throws <InvalidOperationException>(() => dropper.ProcessPipelineData(toProcess, new ThrowImmediatelyDataLoadEventListener(), cts.Token));

            Assert.IsTrue(ex.Message.Contains("does not exist in the supplied data table"));
        }
Пример #6
0
        public void ColumnDropper_Successful()
        {
            var dropper = new ColumnDropper
            {
                ColumnNameToDrop = "ToDrop"
            };

            var cts       = new GracefulCancellationTokenSource();
            var toProcess = new DataTable();

            toProcess.Columns.Add("ToDrop");

            var processed = dropper.ProcessPipelineData(toProcess, new ThrowImmediatelyDataLoadEventListener(), cts.Token);

            Assert.AreEqual(0, processed.Columns.Count);
            Assert.AreEqual(false, processed.Columns.Contains("ToDrop"));
        }
Пример #7
0
        public void ColumnRenamer_Successful()
        {
            var renamer = new ColumnRenamer
            {
                ColumnNameToFind = "ToFind",
                ReplacementName  = "ReplacementName"
            };

            var cts       = new GracefulCancellationTokenSource();
            var toProcess = new DataTable();

            toProcess.Columns.Add("ToFind");

            var processed = renamer.ProcessPipelineData(toProcess, new ThrowImmediatelyDataLoadEventListener(), cts.Token);

            Assert.AreEqual(1, processed.Columns.Count);
            Assert.AreEqual("ReplacementName", processed.Columns[0].ColumnName);
        }
Пример #8
0
        public void TestRoundRobinPipelineExecution()
        {
            // set SetUp two engines, one with a locked cache progress/load schedule
            // run the serial execution and ensure that only one engine had its 'ExecutePipeline' method called
            var engine1     = new Mock <IDataFlowPipelineEngine>();
            var engine2     = new Mock <IDataFlowPipelineEngine>();
            var tokenSource = new GracefulCancellationTokenSource();
            var listener    = new ThrowImmediatelyDataLoadEventListener();

            // first time both engines return that they have more data, second time they are both complete
            engine1.SetupSequence(engine => engine.ExecuteSinglePass(It.IsAny <GracefulCancellationToken>()))
            .Returns(true)
            .Returns(false)
            .Throws <InvalidOperationException>();

            engine2.SetupSequence(engine => engine.ExecuteSinglePass(It.IsAny <GracefulCancellationToken>()))
            .Returns(true)
            .Returns(false)
            .Throws <InvalidOperationException>();

            // set SetUp the engine map
            var loadProgress1 = Mock.Of <ILoadProgress>();
            var loadProgress2 = Mock.Of <ILoadProgress>();

            // set SetUp the lock provider
            var engineMap = new Dictionary <IDataFlowPipelineEngine, ILoadProgress>
            {
                { engine1.Object, loadProgress1 },
                { engine2.Object, loadProgress2 }
            };
            // create the execution object
            var pipelineExecutor = new RoundRobinPipelineExecution();

            // Act
            pipelineExecutor.Execute(new[] { engine1.Object, engine2.Object }, tokenSource.Token, listener);

            // Assert
            // engine1 should have been executed once
            engine1.Verify();

            // engine2 should not have been executed as it is locked
            engine1.Verify();
        }
        /// <summary>
        /// Blocking call which runs a set of DataFlowPipelineEngines according to the execution strategy whilst observing the PermissionWindow.
        /// Stops the task and returns if the PermissionWindow closes.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <param name="cachingEngines"></param>
        /// <returns></returns>
        private RetrievalResult RunOnce(GracefulCancellationToken cancellationToken, List <IDataFlowPipelineEngine> cachingEngines)
        {
            // We will be spawning our own task which we want separate control of (to kill if we pass outside the permission window), so need our own cancellation token
            var executionCancellationTokenSource = new GracefulCancellationTokenSource();

            // We want to be able to stop the engine if we pass outside the permission window, however the execution strategy objects should not know about PermissionWindows
            var executionTask = new Task(() =>
                                         _pipelineEngineExecutionStrategy.Execute(cachingEngines, executionCancellationTokenSource.Token, _listener));

            // Block waiting on task completion or signalling of the cancellation token
            while (!executionTask.IsCompleted)
            {
                if (executionTask.Status == TaskStatus.Created)
                {
                    executionTask.Start();
                }

                Task.Delay(1000).Wait();

                // We need to handle stop and abort as we have used our own cancellation token with the child task
                // If someone above us in the process chain has requested abort or cancel then use our own cancellation token to pass this info on to the child task
                if (cancellationToken.IsAbortRequested)
                {
                    // Wait nicely until the child task signals its abort token (by throwing?)
                    executionCancellationTokenSource.Abort();
                    _listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Have issued Abort request to the Pipeline Execution Task. Waiting for the task to exit..."));
                    try
                    {
                        executionTask.Wait();
                    }
                    catch (AggregateException)
                    {
                    }
                    return(RetrievalResult.Aborted);
                }

                if (cancellationToken.IsStopRequested)
                {
                    // Wait nicely until the child task signals its stop token (by throwing?)
                    executionCancellationTokenSource.Stop();
                    _listener.OnNotify(this,
                                       new NotifyEventArgs(ProgressEventType.Information,
                                                           "Have issued Stop request to the Pipeline Execution Task, however this may take some to complete as it will attempt to complete the current run through the pipeline."));
                    executionTask.Wait();
                    return(RetrievalResult.Stopped);
                }

                // Now can check to see if we are finished (we have passed outside the permission window)
                if (_permissionWindow != null && !_permissionWindow.WithinPermissionWindow())
                {
                    executionCancellationTokenSource.Abort();
                    _listener.OnNotify(this,
                                       new NotifyEventArgs(ProgressEventType.Information,
                                                           "Now outside the PermissionWindow, have issued Abort request to the Pipeline Execution Task."));
                    executionTask.Wait();

                    return(RetrievalResult.NotPermitted);
                }
            }

            if (executionTask.IsFaulted)
            {
                _listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, "Task faulted, information is in the attached exception.", executionTask.Exception));
                throw new InvalidOperationException("Task faulted, see inner exception for details.", executionTask.Exception);
            }

            return(RetrievalResult.Complete);
        }