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()); }
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); } } }
/// <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); } } } }
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); }
public void ExecuteAndForget_EchoStdin_Test() { var cli = new Cli(EchoStdinBat); var input = new ExecutionInput(standardInput: "Hello world"); cli.ExecuteAndForget(input); }
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(); }
/// <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)); } }
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()); }
/// <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); } }
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)); } }
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()); }
/// <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); } }
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();*/ }
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)); } }
/// <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); }
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; } } }
/// <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);
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)); } }
/// <summary> /// Executes CLI with given input, waits until completion and returns output /// </summary> public ExecutionOutput Execute(ExecutionInput input) => Execute(input, CancellationToken.None);
/// <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)); } }
/// <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)); } }
/// <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)); } }
/// <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)); } }
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); } } }
private void ComposeDown() { ExecutionInput input = new ExecutionInput($@"-p {_projectName} -f {_executionPath}\docker-compose.yml down"); _cliCompose.Execute(input, _cancellationTokenSource.Token); }
/// <summary> /// Executes CLI with given input, waits until completion asynchronously and returns output /// </summary> public Task <ExecutionOutput> ExecuteAsync(ExecutionInput input) => ExecuteAsync(input, CancellationToken.None);