public override async Task Run(Func <bool> shutdown) { string closeReason = "Module shutdown"; try { var taskRun = SendVoidRequest(new RunMsg()); while (!shutdown() && !taskRun.IsCompleted && !taskReceive.IsCompleted) { await Task.Delay(TimeSpan.FromSeconds(1)); } if (taskRun.IsCompleted) { closeReason = $"External module {moduleName} returned from Run unexpectedly."; logger.Warn(closeReason); } else if (taskReceive.IsFaulted || process.HasExited) { Thread.Sleep(500); // no need for async wait here closeReason = $"External module {moduleName} terminated unexpectedly."; throw new Exception(closeReason); } else { var taskShutdown = SendVoidRequest(new ShutdownMsg()); Timestamp tStart = Timestamp.Now; const int timeout = 20; while (!taskRun.IsCompleted) { if (taskShutdown.IsFaulted || process.HasExited) { logger.Warn("External module terminated unexpectedly during shutdown."); break; } if (Timestamp.Now - tStart > Duration.FromSeconds(timeout)) { logger.Warn($"Module did not return from Run within {timeout} seconds. Killing process..."); break; } await Task.WhenAny(taskRun, Task.Delay(2000)); if (!taskRun.IsCompleted) { long secondsUntilTimeout = (tStart.AddSeconds(timeout) - Timestamp.Now).TotalMilliseconds / 1000; logger.Info("Waiting for Run completion (timeout in {0} seconds)...", secondsUntilTimeout); } } } } finally { connection.Close(closeReason); StopProcess(process); process = null; } }
public async override Task InitAbort() { if (process == null) { return; // abort already happened in Init() } var taskAbort = SendVoidRequest(new InitAbortMsg()); try { Timestamp tStart = Timestamp.Now; const int timeout = 12; while (!taskAbort.IsCompleted) { if (process.HasExited) { logger.Warn("External module terminated unexpectedly during init abort."); break; } if (Timestamp.Now - tStart > Duration.FromSeconds(timeout)) { logger.Warn($"Module did not return from InitAbort within {timeout} seconds. Killing process..."); break; } await Task.WhenAny(taskAbort, Task.Delay(2000)); if (!taskAbort.IsCompleted) { long secondsUntilTimeout = (tStart.AddSeconds(timeout) - Timestamp.Now).TotalMilliseconds / 1000; logger.Info("Waiting for InitAbort completion (timeout in {0} seconds)...", secondsUntilTimeout); } } } finally { connection.Close("Init abort"); StopProcess(process); process = null; } }