示例#1
0
        public async Task <string> Run(string imageName, Dictionary <string, string> environmentVariables = null, string command = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            StringBuilder result = new StringBuilder();
            StringBuilder error  = new StringBuilder();

            StringBuilder s = new StringBuilder();

            foreach (var key in environmentVariables.Keys)
            {
                s.Append($" -e {key}={environmentVariables[key]} ");
            }

            ExecutionInput input = new ExecutionInput($"run --rm {s.ToString()} {imageName} {command}");



            //input.StandardInput = s.ToString();


            var handler = new BufferHandler(stdOutLine => result.Append(stdOutLine), stdErrLine => error.Append(stdErrLine));

            //if (environmentVariables != null)
            //{
            //    input.EnvironmentVariables = environmentVariables;
            //}
            ExecutionOutput output = await _cliDocker.ExecuteAsync(input, cancellationToken, handler);

            if (output.ExitCode != 0)
            {
                throw new CliException("Could not run image", result.ToString(), error.ToString());
            }
            return(result.ToString());
        }
示例#2
0
        private Process CreateProcess(ExecutionInput input)
        {
            // Create process start info
            var startInfo = new ProcessStartInfo
            {
                FileName               = FilePath,
                WorkingDirectory       = Settings.WorkingDirectory,
                Arguments              = input.Arguments,
                CreateNoWindow         = true,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                RedirectStandardInput  = true,
                StandardOutputEncoding = Settings.Encoding.StandardOutput,
                StandardErrorEncoding  = Settings.Encoding.StandardError,
                UseShellExecute        = false
            };

            // Set environment variables
            startInfo.SetEnvironmentVariables(input.EnvironmentVariables);

            // Create process
            var process = new Process
            {
                StartInfo           = startInfo,
                EnableRaisingEvents = true
            };

            return(process);
        }
        /// <summary>
        /// A simple function that takes a s3 bucket input and extract metadata of Image.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <ImageMetadata> FunctionHandler(ExecutionInput state, ILambdaContext context)
        {
            var tmpPath = Path.Combine(Path.GetTempPath(), Path.GetFileName(state.SourceKey));

            try
            {
                ImageMetadata metadata = new ImageMetadata();
                using (var response = await S3Client.GetObjectAsync(state.Bucket, state.SourceKey))
                {
                    IImageFormat format;

                    using (var sourceImage = Image.Load(response.ResponseStream, out format))
                    {
                        metadata.OrignalImagePixelCount = sourceImage.Width * sourceImage.Height;

                        metadata.Width = sourceImage.Width;

                        metadata.Height = sourceImage.Height;

                        metadata.ExifProfile = sourceImage.Metadata.ExifProfile;

                        metadata.Format = format.Name;
                    }
                }

                return(metadata);
            }
            finally
            {
                if (File.Exists(tmpPath))
                {
                    File.Delete(tmpPath);
                }
            }
        }
        /// <summary>
        ///     A simple function that takes a string and returns both the upper and lower case version of the string.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <List <Label> > FunctionHandler(ExecutionInput input, ILambdaContext context)
        {
            var logger = new ImageRecognitionLogger(input, context);

            Console.WriteLine($"Looking for labels in image {input.Bucket}:{input.SourceKey}");

            var key = WebUtility.UrlDecode(input.SourceKey);

            var detectResponses = await RekognitionClient.DetectLabelsAsync(new DetectLabelsRequest
            {
                MinConfidence = MinConfidence,
                MaxLabels     = MaxLabels,
                Image         = new Image
                {
                    S3Object = new S3Object
                    {
                        Bucket = input.Bucket,
                        Name   = key
                    }
                }
            });

            await logger.WriteMessageAsync(new MessageEvent { Message = "Photo labels extracted successfully" },
                                           ImageRecognitionLogger.Target.All);

            return(detectResponses.Labels);
        }
        public async Task <Mosaic> CreateMosaic(string userId, string galleryId, string name, Stream stream)
        {
            var tempFile = Path.GetTempFileName();

            try
            {
                var mosaicId = name + "-" + Guid.NewGuid().ToString();
                using (var fileStream = File.OpenWrite(tempFile))
                {
                    Utilities.CopyStream(stream, fileStream);
                }

                var putRequest = new PutObjectRequest
                {
                    BucketName = this._appOptions.MosaicStorageBucket,
                    Key        = S3KeyManager.DetermineS3Key(userId, mosaicId, S3KeyManager.ImageType.Original),
                    FilePath   = tempFile
                };
                await this._s3Client.PutObjectAsync(putRequest).ConfigureAwait(false);

                var mosaic = new Mosaic
                {
                    UserId     = userId,
                    MosaicId   = mosaicId,
                    CreateDate = DateTime.UtcNow,
                    Name       = name,
                    Status     = Mosaic.Statuses.Creating
                };

                var input = new ExecutionInput
                {
                    TableGalleryItems = this._appOptions.TableGalleryItems,
                    TableMosaic       = this._appOptions.TableMosaic,
                    Bucket            = this._appOptions.MosaicStorageBucket,
                    SourceKey         = putRequest.Key,
                    GalleryId         = galleryId,
                    MosaicId          = mosaicId,
                    UserId            = userId
                };

                var stepResponse = await this._stepClient.StartExecutionAsync(new StartExecutionRequest
                {
                    StateMachineArn = this._appOptions.StateMachineArn,
                    Name            = $"{Utilities.MakeSafeName(putRequest.Key, 80)}",
                    Input           = JsonConvert.SerializeObject(input)
                }).ConfigureAwait(false);

                mosaic.ExecutionArn = stepResponse.ExecutionArn;
                await this._ddbContext.SaveAsync(mosaic).ConfigureAwait(false);

                return(mosaic);
            }
            finally
            {
                if (File.Exists(tempFile))
                {
                    File.Delete(tempFile);
                }
            }
        }
示例#6
0
        /// <inheritdoc />
        public void ExecuteAndForget(ExecutionInput input)
        {
            input.GuardNotNull(nameof(input));

            // Check if disposed
            ThrowIfDisposed();

            // Create process
            using (var process = CreateProcess(input))
            {
                // Start process
                process.Start();

                // Write stdin
                using (process.StandardInput)
                {
                    if (input.StandardInput != null)
                    {
                        var stdinData   = Settings.Encoding.StandardInput.GetBytes(input.StandardInput);
                        var stdinStream = process.StandardInput.BaseStream;
                        stdinStream.Write(stdinData, 0, stdinData.Length);
                    }
                }
            }
        }
示例#7
0
        private Process CreateProcess(ExecutionInput input)
        {
            // Create process
            var process = new Process
            {
                StartInfo =
                {
                    FileName               = FilePath,
                    WorkingDirectory       = WorkingDirectory,
                    Arguments              = input.Arguments,
                    CreateNoWindow         = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    RedirectStandardInput  = true,
                    UseShellExecute        = false
                },
                EnableRaisingEvents = true
            };

            // Set environment variables
#if NET45
            foreach (var variable in input.EnvironmentVariables)
            {
                process.StartInfo.EnvironmentVariables.Add(variable.Key, variable.Value);
            }
#else
            foreach (var variable in input.EnvironmentVariables)
            {
                process.StartInfo.Environment.Add(variable.Key, variable.Value);
            }
#endif

            return(process);
        }
示例#8
0
        public void ExecuteAndForget_EchoStdin_Test()
        {
            var cli = new Cli(EchoStdinBat);

            var input = new ExecutionInput(standardInput: "Hello world");

            cli.ExecuteAndForget(input);
        }
示例#9
0
        public async Task RunCompose(string yaml)
        {
            File.WriteAllText(Path.Combine(_executionPath, "docker-compose.yml"), yaml);
            ExecutionInput input = new ExecutionInput($@"-p {_projectName} -f {_executionPath}\docker-compose.yml up");

            _cliCompose.ExecuteAndForget(input);

            await WaitForContainerToDie();

            ComposeDown();
        }
示例#10
0
        /// <summary>
        /// Executes CLI with given input, waits until completion asynchronously and returns output
        /// </summary>
        public async Task <ExecutionOutput> ExecuteAsync(ExecutionInput input, CancellationToken cancellationToken)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            // Create task completion source
            var tcs = new TaskCompletionSource <object>();

            // Create process
            using (var process = CreateProcess(input.Arguments))
            {
                // Wire an event that signals task completion
                process.Exited += (sender, args) => tcs.SetResult(null);

                // Start process
                process.Start();

                // Write stdin
                using (process.StandardInput)
                    await process.StandardInput.WriteAsync(input.StandardInput).ConfigureAwait(false);

                // Setup cancellation token
                // This has to be after process start so that it can actually be killed
                // and also after standard input so that it can write correctly
                cancellationToken.Register(() =>
                {
                    // Kill process if it's not dead already
                    // ReSharper disable once AccessToDisposedClosure
                    process.KillIfRunning();
                });

                // Begin reading stdout and stderr
                var stdOutReadTask = process.StandardOutput.ReadToEndAsync();
                var stdErrReadTask = process.StandardError.ReadToEndAsync();

                // Wait until exit
                await tcs.Task.ConfigureAwait(false);

                // Check cancellation
                cancellationToken.ThrowIfCancellationRequested();

                // Get stdout and stderr
                var stdOut = await stdOutReadTask.ConfigureAwait(false);

                var stdErr = await stdErrReadTask.ConfigureAwait(false);

                return(new ExecutionOutput(process.ExitCode, stdOut, stdErr));
            }
        }
示例#11
0
        public void Execute_EchoStdin_Test()
        {
            var cli = new Cli(EchoStdinBat);

            var input  = new ExecutionInput(standardInput: "Hello world");
            var output = cli.Execute(input);

            output.ThrowIfError();

            Assert.IsNotNull(output);
            Assert.AreEqual(14, output.ExitCode);
            Assert.AreEqual("Hello world", output.StandardOutput.TrimEnd());
            Assert.AreEqual("", output.StandardError.TrimEnd());
        }
示例#12
0
        /// <summary>
        /// Executes target process with given input, without waiting for completion.
        /// </summary>
        /// <param name="input">Execution input.</param>
        public void ExecuteAndForget(ExecutionInput input)
        {
            input.GuardNotNull(nameof(input));

            // Create process
            using (var process = CreateProcess(input))
            {
                // Start process
                process.Start();

                // Write stdin
                using (process.StandardInput)
                    process.StandardInput.Write(input.StandardInput);
            }
        }
示例#13
0
        public void Execute_EchoStdinToStdout_Test()
        {
            using (var cli = new Cli(_echoStdinToStdoutBat))
            {
                var input  = new ExecutionInput(standardInput: TestString);
                var output = cli.Execute(input);
                output.ThrowIfError();

                Assert.That(output, Is.Not.Null);
                Assert.That(output.ExitCode, Is.EqualTo(TestExitCode));
                Assert.That(output.StandardOutput.TrimEnd(), Is.EqualTo(TestString));
                Assert.That(output.StandardError.TrimEnd(), Is.Empty);
                Assert.That(output.StartTime, Is.LessThanOrEqualTo(output.ExitTime));
                Assert.That(output.RunTime, Is.EqualTo(output.ExitTime - output.StartTime));
            }
        }
示例#14
0
        public void Execute_EchoEnvVar_Test()
        {
            var cli = new Cli(EchoEnvVarBat);

            var input = new ExecutionInput();

            input.EnvironmentVariables.Add("TEST_ENV_VAR", "Hello world");

            var output = cli.Execute(input);

            output.ThrowIfError();

            Assert.IsNotNull(output);
            Assert.AreEqual(14, output.ExitCode);
            Assert.AreEqual("Hello world", output.StandardOutput.TrimEnd());
            Assert.AreEqual("", output.StandardError.TrimEnd());
        }
示例#15
0
        /// <summary>
        /// Executes CLI with given input, without waiting for completion
        /// </summary>
        public void ExecuteAndForget(ExecutionInput input)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            // Create process
            using (var process = CreateProcess(input.Arguments))
            {
                // Start process
                process.Start();

                // Write stdin
                using (process.StandardInput)
                    process.StandardInput.Write(input.StandardInput);
            }
        }
示例#16
0
        private string ExecuteBinary(string file)
        {
            StringBuilder ret = new StringBuilder();

            string filePath = Path.GetFullPath(file);

            var cli = new Cli(_Installation.PhpExecutablePath);

            var execInput = new ExecutionInput($"-f \"{filePath}\"");

            var cts = new CancellationTokenSource();

            cts.CancelAfter(TimeSpan.FromSeconds(_Installation.ExecutionTimeout));

            var output = cli.Execute(execInput, cts.Token);

            return(output.StandardOutput);

            /*ProcessStartInfo psi = new ProcessStartInfo();
             * psi.FileName = _Installation.PhpExecutablePath;
             * psi.Arguments = $"-f \"{filePath}\"";
             * //psi.EnvironmentVariables.Add("")
             * psi.UseShellExecute = false;
             * psi.RedirectStandardOutput = true;
             *
             * Process p = new Process();
             * p.StartInfo = psi;
             *
             * p.Start();
             *
             * Task.Delay(_Installation.ExecutionTimeout).ContinueWith((t) =>
             * {
             *  if (!p.HasExited)
             *      p.Kill();
             * });
             *
             * while (!p.StandardOutput.EndOfStream)
             * {
             *  string line = p.StandardOutput.ReadLine();
             *  ret.AppendLine(line);
             * }
             *
             * return ret.ToString();*/
        }
示例#17
0
        public async Task ExecuteAsync_EchoEnvVarToStdout_Test()
        {
            using (var cli = new Cli(_echoEnvVarToStdoutBat))
            {
                var input = new ExecutionInput();
                input.EnvironmentVariables.Add(TestEnvVar, TestString);

                var output = await cli.ExecuteAsync(input);

                output.ThrowIfError();

                Assert.That(output, Is.Not.Null);
                Assert.That(output.ExitCode, Is.EqualTo(TestExitCode));
                Assert.That(output.StandardOutput.TrimEnd(), Is.EqualTo(TestString));
                Assert.That(output.StandardError.TrimEnd(), Is.Empty);
                Assert.That(output.StartTime, Is.LessThanOrEqualTo(output.ExitTime));
                Assert.That(output.RunTime, Is.EqualTo(output.ExitTime - output.StartTime));
            }
        }
示例#18
0
        /// <summary>
        ///     A simple function that takes a s3 bucket input and extract metadata of Image.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <ImageMetadata> FunctionHandler(ExecutionInput state, ILambdaContext context)
        {
            var logger = new ImageRecognitionLogger(state, context);

            var srcKey  = WebUtility.UrlDecode(state.SourceKey);
            var tmpPath = Path.Combine(Path.GetTempPath(), Path.GetFileName(srcKey));

            try
            {
                var metadata = new ImageMetadata();
                using (var response = await S3Client.GetObjectAsync(state.Bucket, srcKey))
                {
                    using (var sourceImage = Image.Load(response.ResponseStream, out var format))
                    {
                        metadata.OriginalImagePixelCount = sourceImage.Width * sourceImage.Height;

                        metadata.Width = sourceImage.Width;

                        metadata.Height = sourceImage.Height;

                        metadata.ExifProfile = sourceImage.Metadata.ExifProfile;

                        metadata.Format = format.Name;
                    }
                }

                await logger.WriteMessageAsync(new MessageEvent { Message = "Photo metadata extracted succesfully" },
                                               ImageRecognitionLogger.Target.All);

                return(metadata);
            }
            finally
            {
                if (File.Exists(tmpPath))
                {
                    File.Delete(tmpPath);
                }
            }
        }
        /// <summary>
        /// A simple function that takes a string and returns both the upper and lower case version of the string.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <List <Label> > FunctionHandler(ExecutionInput input, ILambdaContext context)
        {
            Console.WriteLine($"Looking for labels in image {input.Bucket}:{input.SourceKey}");

            string key = System.Web.HttpUtility.UrlDecode(input.SourceKey);

            var detectResponses = await this.RekognitionClient.DetectLabelsAsync(new DetectLabelsRequest
            {
                MinConfidence = MinConfidence,
                MaxLabels     = MaxLabels,
                Image         = new Image
                {
                    S3Object = new Amazon.Rekognition.Model.S3Object
                    {
                        Bucket = input.Bucket,
                        Name   = input.SourceKey
                    }
                }
            });

            return(detectResponses.Labels);
        }
示例#20
0
        private async Task WaitForContainerToDie()
        {
            ExecutionInput          input = new ExecutionInput($@"events --filter com.docker.compose.project={_projectName} --filter event=die");
            CancellationTokenSource monitorTokenSource = new CancellationTokenSource();
            var linkedTokens = CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token, monitorTokenSource.Token);

            var handler = new BufferHandler(
                stdOutLine => monitorTokenSource.Cancel(), // We received the info we were waiting for
                stdErrLine => monitorTokenSource.Cancel());

            try
            {
                await _cliDocker.ExecuteAsync(input, linkedTokens.Token, handler);
            }
            catch (OperationCanceledException e)
            {
                // Only throw the cancelltion exception if the global token was cancelled
                if (_cancellationTokenSource.IsCancellationRequested)
                {
                    throw;
                }
            }
        }
示例#21
0
 /// <summary>
 /// Executes CLI with given input, waits until completion asynchronously and returns output
 /// </summary>
 public async Task <ExecutionOutput> ExecuteAsync(ExecutionInput input)
 => await ExecuteAsync(input, CancellationToken.None).ConfigureAwait(false);
示例#22
0
        public async Task <ExecutionOutput> Execute1Async(ExecutionInput input,
                                                          CancellationToken cancellationToken = default(CancellationToken),
                                                          IBufferHandler bufferHandler        = null)
        {
            input.GuardNotNull(nameof(input));

            // Check if disposed
            ThrowIfDisposed();

            // Create task completion sources
            var processTcs = new TaskCompletionSource <object>();
            var stdOutTcs  = new TaskCompletionSource <object>();
            var stdErrTcs  = new TaskCompletionSource <object>();

            // Set up execution context
            using (var process = CreateProcess1(input))
            {
                // Get linked cancellation token
                var linkedToken = cancellationToken;

                // Create buffers
                var stdOutBuffer = new StringBuilder();
                var stdErrBuffer = new StringBuilder();

                // Wire events
                process.Exited             += (sender, args) => processTcs.TrySetResult(null);
                process.OutputDataReceived += (sender, args) =>
                {
                    if (args.Data != null)
                    {
                        stdOutBuffer.AppendLine(args.Data);
                        bufferHandler?.HandleStandardOutput(args.Data);
                    }
                    else
                    {
                        stdOutTcs.TrySetResult(null);
                    }
                };
                process.ErrorDataReceived += (sender, args) =>
                {
                    if (args.Data != null)
                    {
                        stdErrBuffer.AppendLine(args.Data);
                        bufferHandler?.HandleStandardError(args.Data);
                    }
                    else
                    {
                        stdErrTcs.TrySetResult(null);
                    }
                };

                // Start process
                process.Start();
                var startTime = DateTimeOffset.Now;

                // Begin reading stdout and stderr
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();

                // Write stdin
                using (process.StandardInput)
                {
                    var sr = new StreamWriter(process.StandardInput.BaseStream, Encoding.GetEncoding("GBK"));
                    //sr.WriteLine("chcp 65001");
                    sr.WriteLine(input.Arguments);
                    sr.Flush();
                }

                // Setup cancellation token to kill process and cancel tasks
                // This has to be after process start so that it can actually be killed
                // and also after standard input so that it can write correctly
                linkedToken.Register(() =>
                {
                    CloseCmdProcess.CloseProcess(process);
                    process.TryKill();
                    processTcs.TrySetCanceled();
                    stdOutTcs.TrySetCanceled();
                    stdErrTcs.TrySetCanceled();
                });

                // Wait until exit
                await processTcs.Task.ConfigureAwait(false);

                var exitTime = DateTimeOffset.Now;

                // Wait until stdout and stderr finished reading
                await stdOutTcs.Task.ConfigureAwait(false);

                await stdErrTcs.Task.ConfigureAwait(false);

                // Get stdout and stderr
                var stdOut = stdOutBuffer.ToString();
                var stdErr = stdErrBuffer.ToString();

                return(new ExecutionOutput(process.ExitCode, stdOut, stdErr, startTime, exitTime));
            }
        }
示例#23
0
 /// <summary>
 /// Executes CLI with given input, waits until completion and returns output
 /// </summary>
 public ExecutionOutput Execute(ExecutionInput input)
 => Execute(input, CancellationToken.None);
示例#24
0
        /// <inheritdoc />
        public ExecutionOutput Execute(ExecutionInput input,
                                       CancellationToken cancellationToken = default(CancellationToken),
                                       IBufferHandler bufferHandler        = null)
        {
            input.GuardNotNull(nameof(input));

            // Check if disposed
            ThrowIfDisposed();

            // Set up execution context
            using (var processMre = new ManualResetEventSlim())
                using (var stdOutMre = new ManualResetEventSlim())
                    using (var stdErrMre = new ManualResetEventSlim())
                        using (var linkedCts = LinkCancellationToken(cancellationToken))
                            using (var process = CreateProcess(input))
                            {
                                // Get linked cancellation token
                                var linkedToken = linkedCts.Token;

                                // Create buffers
                                var stdOutBuffer = new StringBuilder();
                                var stdErrBuffer = new StringBuilder();

                                // Wire events
                                process.Exited             += (sender, args) => processMre.Set();
                                process.OutputDataReceived += (sender, args) =>
                                {
                                    if (args.Data != null)
                                    {
                                        stdOutBuffer.AppendLine(args.Data);
                                        bufferHandler?.HandleStandardOutput(args.Data);
                                    }
                                    else
                                    {
                                        stdOutMre.Set();
                                    }
                                };
                                process.ErrorDataReceived += (sender, args) =>
                                {
                                    if (args.Data != null)
                                    {
                                        stdErrBuffer.AppendLine(args.Data);
                                        bufferHandler?.HandleStandardError(args.Data);
                                    }
                                    else
                                    {
                                        stdErrMre.Set();
                                    }
                                };

                                // Start process
                                process.Start();
                                var startTime = DateTimeOffset.Now;

                                // Begin reading stdout and stderr
                                process.BeginOutputReadLine();
                                process.BeginErrorReadLine();

                                // Write stdin
                                using (process.StandardInput)
                                {
                                    if (input.StandardInput != null)
                                    {
                                        var stdinData   = Settings.Encoding.StandardInput.GetBytes(input.StandardInput);
                                        var stdinStream = process.StandardInput.BaseStream;
                                        stdinStream.Write(stdinData, 0, stdinData.Length);
                                    }
                                }

                                // Setup cancellation token to kill process and set events
                                // This has to be after process start so that it can actually be killed
                                // and also after standard input so that it can write correctly
                                linkedToken.Register(() =>
                                {
                                    process.TryKill();
                                    processMre.Set();
                                    stdOutMre.Set();
                                    stdErrMre.Set();
                                });

                                // Cancellation token is not passed to waits because
                                // the callback has to finish executing before the process is disposed
                                // which otherwise would happen too soon

                                // Wait until exit
                                processMre.Wait();
                                var exitTime = DateTimeOffset.Now;

                                // Wait until stdout and stderr finished reading
                                stdOutMre.Wait();
                                stdErrMre.Wait();

                                // Check cancellation
                                linkedToken.ThrowIfCancellationRequested();

                                // Get stdout and stderr
                                var stdOut = stdOutBuffer.ToString();
                                var stdErr = stdErrBuffer.ToString();

                                return(new ExecutionOutput(process.ExitCode, stdOut, stdErr, startTime, exitTime));
                            }
        }
示例#25
0
        /// <summary>
        /// Executes target process with given input, waits until completion asynchronously and returns produced output.
        /// </summary>
        /// <param name="input">Execution input.</param>
        /// <param name="cancellationToken">Token that can be used to abort execution.</param>
        /// <param name="bufferHandler">Handler for real-time standard output and standard error data.</param>
        /// <remarks>The underlying process is killed if the execution is canceled.</remarks>
        public async Task <ExecutionOutput> ExecuteAsync(ExecutionInput input,
                                                         CancellationToken cancellationToken = default(CancellationToken),
                                                         IBufferHandler bufferHandler        = null)
        {
            input.GuardNotNull(nameof(input));

            // Create task completion sources
            var processTcs = new TaskCompletionSource <object>();
            var stdOutTcs  = new TaskCompletionSource <object>();
            var stdErrTcs  = new TaskCompletionSource <object>();

            // Set up execution context
            using (var process = CreateProcess(input))
                using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _killSwitchCts.Token))
                {
                    // Get linked cancellation token
                    var linkedToken = linkedCts.Token;

                    // Create buffers
                    var stdOutBuffer = new StringBuilder();
                    var stdErrBuffer = new StringBuilder();

                    // Wire events
                    process.Exited             += (sender, args) => processTcs.SetResult(null);
                    process.OutputDataReceived += (sender, args) =>
                    {
                        if (args.Data != null)
                        {
                            stdOutBuffer.AppendLine(args.Data);
                            bufferHandler?.HandleStandardOutput(args.Data);
                        }
                        else
                        {
                            stdOutTcs.SetResult(null);
                        }
                    };
                    process.ErrorDataReceived += (sender, args) =>
                    {
                        if (args.Data != null)
                        {
                            stdErrBuffer.AppendLine(args.Data);
                            bufferHandler?.HandleStandardError(args.Data);
                        }
                        else
                        {
                            stdErrTcs.SetResult(null);
                        }
                    };

                    // Start process
                    process.Start();
                    var startTime = DateTimeOffset.Now;

                    // Begin reading stdout and stderr
                    process.BeginOutputReadLine();
                    process.BeginErrorReadLine();

                    // Write stdin
                    using (process.StandardInput)
                        await process.StandardInput.WriteAsync(input.StandardInput).ConfigureAwait(false);

                    // Setup cancellation token
                    // This has to be after process start so that it can actually be killed
                    // and also after standard input so that it can write correctly
                    linkedToken.Register(() =>
                    {
                        // Kill process if it's not dead already
                        process.KillIfRunning();

                        // Cancel tasks
                        processTcs.SetCanceled();
                        stdOutTcs.SetCanceled();
                        stdErrTcs.SetCanceled();
                    });

                    // Wait until exit
                    await processTcs.Task.ConfigureAwait(false);

                    var exitTime = DateTimeOffset.Now;

                    // Wait until stdout and stderr finished reading
                    await stdOutTcs.Task.ConfigureAwait(false);

                    await stdErrTcs.Task.ConfigureAwait(false);

                    // Get stdout and stderr
                    var stdOut = stdOutBuffer.ToString();
                    var stdErr = stdErrBuffer.ToString();

                    return(new ExecutionOutput(process.ExitCode, stdOut, stdErr, startTime, exitTime));
                }
        }
示例#26
0
        /// <summary>
        /// Executes target process with given input, waits until completion synchronously and returns produced output.
        /// </summary>
        /// <param name="input">Execution input.</param>
        /// <param name="cancellationToken">Token that can be used to abort execution.</param>
        /// <param name="bufferHandler">Handler for real-time standard output and standard error data.</param>
        /// <remarks>The underlying process is killed if the execution is canceled.</remarks>
        public ExecutionOutput Execute(ExecutionInput input,
                                       CancellationToken cancellationToken = default(CancellationToken),
                                       IBufferHandler bufferHandler        = null)
        {
            input.GuardNotNull(nameof(input));

            // Set up execution context
            using (var stdOutMre = new ManualResetEventSlim())
                using (var stdErrMre = new ManualResetEventSlim())
                    using (var process = CreateProcess(input))
                        using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _killSwitchCts.Token))
                        {
                            // Get linked cancellation token
                            var linkedToken = linkedCts.Token;

                            // Create buffers
                            var stdOutBuffer = new StringBuilder();
                            var stdErrBuffer = new StringBuilder();

                            // Wire events
                            process.OutputDataReceived += (sender, args) =>
                            {
                                if (args.Data != null)
                                {
                                    stdOutBuffer.AppendLine(args.Data);
                                    bufferHandler?.HandleStandardOutput(args.Data);
                                }
                                else
                                {
                                    stdOutMre.Set();
                                }
                            };
                            process.ErrorDataReceived += (sender, args) =>
                            {
                                if (args.Data != null)
                                {
                                    stdErrBuffer.AppendLine(args.Data);
                                    bufferHandler?.HandleStandardError(args.Data);
                                }
                                else
                                {
                                    stdErrMre.Set();
                                }
                            };

                            // Start process
                            process.Start();
                            var startTime = DateTimeOffset.Now;

                            // Begin reading stdout and stderr
                            process.BeginOutputReadLine();
                            process.BeginErrorReadLine();

                            // Write stdin
                            using (process.StandardInput)
                                process.StandardInput.Write(input.StandardInput);

                            // Setup cancellation token
                            // This has to be after process start so that it can actually be killed
                            // and also after standard input so that it can write correctly
                            linkedToken.Register(() =>
                            {
                                // Kill process if it's not dead already
                                process.KillIfRunning();
                            });

                            // Wait until exit
                            process.WaitForExit();
                            var exitTime = DateTimeOffset.Now;

                            // Check cancellation
                            linkedToken.ThrowIfCancellationRequested();

                            // Wait until stdout and stderr finished reading
                            stdOutMre.Wait(linkedToken);
                            stdErrMre.Wait(linkedToken);

                            // Get stdout and stderr
                            var stdOut = stdOutBuffer.ToString();
                            var stdErr = stdErrBuffer.ToString();

                            return(new ExecutionOutput(process.ExitCode, stdOut, stdErr, startTime, exitTime));
                        }
        }
示例#27
0
        /// <summary>
        /// Executes CLI with given input, waits until completion and returns output
        /// </summary>
        public ExecutionOutput Execute(ExecutionInput input, CancellationToken cancellationToken)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            // Create process
            using (var process = CreateProcess(input.Arguments))
            {
                // Create buffers
                var stdOutBuffer = new StringBuilder();
                var stdErrBuffer = new StringBuilder();

                // Wire events
                process.OutputDataReceived += (sender, args) =>
                {
                    if (args.Data != null)
                    {
                        stdOutBuffer.AppendLine(args.Data);
                    }
                };
                process.ErrorDataReceived += (sender, args) =>
                {
                    if (args.Data != null)
                    {
                        stdErrBuffer.AppendLine(args.Data);
                    }
                };

                // Start process
                process.Start();

                // Write stdin
                using (process.StandardInput)
                    process.StandardInput.Write(input.StandardInput);

                // Setup cancellation token
                // This has to be after process start so that it can actually be killed
                // and also after standard input so that it can write correctly
                cancellationToken.Register(() =>
                {
                    // Kill process if it's not dead already
                    // ReSharper disable once AccessToDisposedClosure
                    process.KillIfRunning();
                });

                // Begin reading stdout and stderr
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();

                // Wait until exit
                process.WaitForExit();

                // Check cancellation
                cancellationToken.ThrowIfCancellationRequested();

                // Get stdout and stderr
                var stdOut = stdOutBuffer.ToString();
                var stdErr = stdErrBuffer.ToString();

                return(new ExecutionOutput(process.ExitCode, stdOut, stdErr));
            }
        }
示例#28
0
        static void Main(string[] args)
        {
            // Initialize the interfaces
            using (var myOrderProcessingApi = new ApiWrapper <OrderProcessingAPI>())
            {
                ClientApiOptions clientApiOptions = new ClientApiOptions(); //fill this object to override default xcApi parameters

                if (myOrderProcessingApi.Init(myOrderProcessingApi.Api.DefaultXcApiFileName, clientApiOptions))
                {
                    int orderId = 0;
                    using (var orderCreationEvent = new AutoResetEvent(false))
                    {
                        // Subscribe to new order instances
                        myOrderProcessingApi.Api.Order_Component.Order_StateMachine.Pending_State.InstanceUpdated +=
                            instance =>
                        {
                            Console.WriteLine("New order pending for execution: " + DisplayOrder(instance));
                            orderId = instance.PublicMember.Id;
                            orderCreationEvent.Set();
                        };

                        myOrderProcessingApi.Api.Order_Component.Order_StateMachine.PartiallyExecuted_State
                        .InstanceUpdated +=
                            instance =>
                        {
                            Console.WriteLine("Order partially filled: " + DisplayOrder(instance));
                        };

                        myOrderProcessingApi.Api.Order_Component.Order_StateMachine.Executed_State.InstanceUpdated +=
                            instance =>
                        {
                            Console.WriteLine("Order filled: " + DisplayOrder(instance));
                        };

                        myOrderProcessingApi.Api.Trade_Component.Trade_StateMachine.WaitingForExecution_State
                        .InstanceUpdated +=
                            instance =>
                        {
                            Console.WriteLine("Trade waiting for execution: " + DisplayTrade(instance));
                        };

                        myOrderProcessingApi.Api.Trade_Component.Trade_StateMachine.Executed_State.InstanceUpdated +=
                            instance =>
                        {
                            Console.WriteLine("Trade executed : " + DisplayTrade(instance));
                        };

                        // Create an order
                        OrderInput orderInput = new OrderInput
                        {
                            AssetName = "INVIVOO",
                            Quantity  = 1000
                        };

                        myOrderProcessingApi.Api.Order_Component.OrderProcessor_StateMachine.SendEvent(orderInput);
                        orderCreationEvent.WaitOne(1000);

                        // Partially fill the order
                        ExecutionInput executionInput = new ExecutionInput
                        {
                            OrderId  = orderId,
                            Quantity = 250,
                            Price    = 102
                        };

                        myOrderProcessingApi.Api.Order_Component.Order_StateMachine.SendEvent(executionInput);

                        // Fill the order
                        executionInput = new ExecutionInput
                        {
                            OrderId  = orderId,
                            Quantity = 750,
                            Price    = 101.5,
                        };
                        myOrderProcessingApi.Api.Order_Component.Order_StateMachine.SendEvent(executionInput);

                        Console.ReadKey();
                    }
                }
                else
                {
                    AnalyseReport(myOrderProcessingApi.Report);
                }
            }
        }
示例#29
0
        private void ComposeDown()
        {
            ExecutionInput input = new ExecutionInput($@"-p {_projectName} -f {_executionPath}\docker-compose.yml down");

            _cliCompose.Execute(input, _cancellationTokenSource.Token);
        }
示例#30
0
 /// <summary>
 /// Executes CLI with given input, waits until completion asynchronously and returns output
 /// </summary>
 public Task <ExecutionOutput> ExecuteAsync(ExecutionInput input)
 => ExecuteAsync(input, CancellationToken.None);