/// <summary>
        /// Creates a cancellable task that runs SAPS on the given instance.
        /// </summary>
        /// <param name="instance">Instance to run on.</param>
        /// <param name="cancellationToken">Token that is regularly checked for cancellation.
        /// If cancellation is detected, the task will be stopped.</param>
        /// <returns>A task that has returns the run's runtime on completion.</returns>
        public Task <RuntimeResult> Run(InstanceSeedFile instance, CancellationToken cancellationToken)
        {
            // Define process to start SAPS.
            var processInfo = this.BuildProcessStartInfo(instance);

            return(Task.Run(
                       function: () =>
            {
                // Start process.
                using var process = Process.Start(processInfo);

                // Process needs to be canceled if cancellation token is canceled.
                var processRegistration = cancellationToken.Register(
                    () => ProcessUtils.CancelProcess(process));

                // Wait until end of process.
                process.WaitForExit();

                // If the process was cancelled, clean up resources and escalate it up.
                if (cancellationToken.IsCancellationRequested)
                {
                    SapsRunner.CleanUp(process, processRegistration);
                    cancellationToken.ThrowIfCancellationRequested();
                }

                // If the process was not cancelled, first check the output for CPU time.
                var output = process.StandardOutput.ReadToEnd();

                // Then clean up resources.
                SapsRunner.CleanUp(process, processRegistration);

                return SapsRunner.CreateRuntimeResult(output, this._timeout);
            },
                       cancellationToken: cancellationToken));
        }
        public void CancelProcessWorksOnExitedProcess()
        {
            // Cancel once.
            ProcessUtils.CancelProcess(this._process);
            Assert.True(this._process.HasExited);

            // Cancel twice - no exception should be thrown.
            ProcessUtils.CancelProcess(this._process);
        }
예제 #3
0
        /// <summary>
        /// Creates a cancellable task that runs a target algorithm on the given instance.
        /// </summary>
        /// <param name="instance">Instance to run on.</param>
        /// <param name="cancellationToken">Token that is regularly checked for cancellation.
        /// If cancellation is detected, the task will be stopped.</param>
        /// <returns>A task that returns statistics about the run on completion.</returns>
        public Task <TResult> Run(InstanceSeedFile instance, CancellationToken cancellationToken)
        {
            // Define process to target algorithm from command line.
            var processInfo = this.BuildProcessStartInfo(instance);

            // Make sure output and Error stores are clean.
            this.Output.Clear();
            this.Error.Clear();

            return(Task.Run(
                       function: () =>
            {
                // Start process and make sure it's cancelled if the cancellationToken is cancelled.
                using (var process = Process.Start(processInfo))
                    using (var processRegistration =
                               cancellationToken.Register(() => ProcessUtils.CancelProcess(process)))
                    {
                        LoggingHelper.WriteLine(VerbosityLevel.Trace, "Started process.");

                        // Catch all output.
                        // Read streams asynchronously to prevent deadlocks.
                        process.OutputDataReceived += (s, e) => this.Output.AppendLine(e.Data);
                        process.ErrorDataReceived += (s, e) => this.Error.AppendLine(e.Data);
                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();

                        // Wait until end of process.
                        process.WaitForExit();

                        if (cancellationToken.IsCancellationRequested)
                        {
                            this.HandleCancellation(process, cancellationToken);
                        }

                        // Parse result.
                        OriginalRunResult originalRunResult;
                        try
                        {
                            originalRunResult = this.ExtractRunResult();
                        }
                        catch (Exception)
                        {
                            // Write information to file if anything goes wrong.
                            this.WriteProcessOutputToFiles(process);
                            throw;
                        }

                        var result = this.CreateRunResult(originalRunResult);
                        LoggingHelper.WriteLine(VerbosityLevel.Debug, $"Result: {result}");

                        return result;
                    }
            },
                       cancellationToken: cancellationToken));
        }
예제 #4
0
        /// <summary>
        /// Creates a cancellable task that runs the <see cref="CommandExecutorBase{TResult}.Command"/> on the given instance.
        /// </summary>
        /// <param name="instance">Instance to run on.</param>
        /// <param name="cancellationToken">Token that is regurlarly checked for cancellation.
        /// If cancellation is detected, the task will be stopped.</param>
        /// <returns>A task that returns the run's result on completion.</returns>
        public override Task <ContinuousResult> Run(InstanceFile instance, CancellationToken cancellationToken)
        {
            // Define process and redirect standard output to read value to optimize from output.
            var processInfo = this.BuildProcessStartInfo(instance);

            processInfo.RedirectStandardOutput = true;

            return(Task.Run(
                       function: () =>
            {
                // Start process.
                var timer = new Stopwatch();
                timer.Start();
                using (var process = Process.Start(processInfo))
                    using (var processRegistration =
                               cancellationToken.Register(() => ProcessUtils.CancelProcess(process)))
                    {
                        // Wait until end of process.
                        process.WaitForExit();

                        // If the process was cancelled, clean up resources and escalate it up.
                        if (cancellationToken.IsCancellationRequested)
                        {
                            this.CleanUp(process);
                            cancellationToken.ThrowIfCancellationRequested();
                        }

                        // If the process has inappropriate exit code, clean up resources and return cancelled result.
                        if (process.ExitCode != 0)
                        {
                            this.CleanUp(process);
                            return ContinuousResult.CreateCancelledResult(this._timeout);
                        }

                        // If the process was not cancelled, find the last value written to console.
                        string output = process.StandardOutput.ReadToEnd();
                        timer.Stop();

                        // If the output does not match to regex, clean up resources and return cancelled result.
                        if (!ValueReadingExecutor.NumberMatcher.IsMatch(output))
                        {
                            this.CleanUp(process);
                            return ContinuousResult.CreateCancelledResult(this._timeout);
                        }

                        // If the output matches to regex, clean up resources and return the founded output as result.
                        double value = double.Parse(ValueReadingExecutor.NumberMatcher.Match(output).Value, CultureInfo.InvariantCulture);
                        this.CleanUp(process);
                        return new ContinuousResult(value, timer.Elapsed);
                    }
            },
                       cancellationToken: cancellationToken));
        }
예제 #5
0
        /// <summary>
        /// Creates a cancellable task that runs the algorithm on the given instance.
        /// </summary>
        /// <param name="instance">Instance to run on.</param>
        /// <param name="cancellationToken">Token that should regurlarly be checked for cancellation.
        /// If cancellation is detected, the task has to be stopped.</param>
        /// <returns>
        /// A task that returns everything important about the run on completion.
        /// </returns>
        public Task <ContinuousResult> Run(InstanceFile instance, CancellationToken cancellationToken)
        {
            // Define process to start BBOB.
            var processInfo = this.BuildProcessStartInfo(instance);

            return(Task.Run(
                       function: () =>
            {
                // Start process.
                var timer = new Stopwatch();
                timer.Start();
                using var process = Process.Start(processInfo);
                // Process needs to be canceled if cancellation token is canceled.
                var processRegistration = cancellationToken.Register(
                    () => ProcessUtils.CancelProcess(process));

                // Wait until end of process.
                process.WaitForExit();

                // If the process was cancelled, clean up resources and escalate it up.
                if (cancellationToken.IsCancellationRequested)
                {
                    this.CleanUp(process, processRegistration);
                    cancellationToken.ThrowIfCancellationRequested();
                }

                // If the process was not cancelled, first check the console output for result.
                var output = process.StandardOutput.ReadToEnd();
                timer.Stop();

                var functionValue = BbobRunner.ExtractFunctionValue(output);

                // Then clean up resources.
                this.CleanUp(process, processRegistration);

                // Finally return the result.
                return new ContinuousResult(functionValue, timer.Elapsed);
            },
                       cancellationToken: cancellationToken));
        }
예제 #6
0
        /// <summary>
        /// Creates a cancellable task that runs the <see cref="CommandExecutorBase{TResult}.Command"/> on the given instance.
        /// </summary>
        /// <param name="instance">Instance to run on.</param>
        /// <param name="cancellationToken">Token that is regurlarly checked for cancellation.
        /// If cancellation is detected, the task will be stopped.</param>
        /// <returns>A task that returns the run's runtime on completion.</returns>
        public override Task <RuntimeResult> Run(InstanceFile instance, CancellationToken cancellationToken)
        {
            // Define process to target algorithm from command line.
            var processInfo = this.BuildProcessStartInfo(instance);

            return(Task.Run(
                       function: () =>
            {
                var timer = new Stopwatch();
                timer.Start();
                // Start process and make sure it's cancelled if the cancellationToken is cancelled.
                using (var process = Process.Start(processInfo))
                    using (var processRegistration =
                               cancellationToken.Register(() => ProcessUtils.CancelProcess(process)))
                    {
                        // Wait until end of process.
                        process.WaitForExit();

                        // If the process was cancelled, escalate it up.
                        if (cancellationToken.IsCancellationRequested)
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                        }

                        // If the process has inappropriate exit code, clean up resources and return cancelled result.
                        if (process.ExitCode != 0)
                        {
                            return RuntimeResult.CreateCancelledResult(this._timeout);
                        }

                        // If the process was not cancelled, return CPU time as result.
                        timer.Stop();
                        return new RuntimeResult(timer.Elapsed);
                    }
            },
                       cancellationToken: cancellationToken));
        }
 public void CancelProcessCancelsProcess()
 {
     ProcessUtils.CancelProcess(this._process);
     Assert.True(this._process.HasExited);
 }
 public void CancelProcessThrowsOnDisposedProcess()
 {
     this._process.Dispose();
     Assert.Throws <InvalidOperationException>(() => ProcessUtils.CancelProcess(this._process));
 }