public async Task When_server_signals_exit_then_should_notifiy_client_to_exit() { var exitCalled = new TaskCompletionSource <bool>(); var listener = await CooperativeShutdown.Listen( () => exitCalled.SetResult(true)); await CooperativeShutdown.SignalExit(Process.GetCurrentProcess().Id); (await exitCalled.Task.TimeoutAfter(TimeSpan.FromSeconds(2))).ShouldBeTrue(); listener.Dispose(); }
public async Task When_server_signals_exit_then_should_notify_client_to_exit() { var exitCalled = new TaskCompletionSource <bool>(); var listener = await CooperativeShutdown.Listen( () => exitCalled.SetResult(true), _loggerFactory); await CooperativeShutdown.SignalExit(Process.GetCurrentProcess().Id, _loggerFactory); (await exitCalled.Task).ShouldBeTrue(); listener.Dispose(); }
private async Task OnStop(TimeSpan?timeout) { if (!timeout.HasValue || timeout.Value <= TimeSpan.Zero) { try { _logger.Info($"Killing process {_process.Id}"); _process.Kill(); } catch (Exception ex) { _logger.WarnException( $"Exception occurred attempting to kill process {_process.Id}. This may if the " + "in the a race condition where process has already exited and an attempt to kill it.", ex); } } else { try { // Signal process to exit. If no response from process (busy or // doesn't support signaling, then this will timeout. Note: a // process acknowledging that it has received an EXIT signal // only means the process has _started_ to shut down. // TODO detect if the app hasn't shut down in the allotted time and if so, kill it. await CooperativeShutdown.SignalExit(ProcessInfo.Id).TimeoutAfter(timeout.Value); } catch (TimeoutException) { // Process doesn't support EXIT signal OR it didn't response in // time so Kill it. Note: still a race condition - the EXIT // signal may have been received but just not acknowledged in // time. try { _process.Kill(); } catch (Exception ex) { _logger.WarnException( $"Exception occurred attempting to kill process {_process.Id}. This may if the " + "in the a race condition where process has already exited and an attempt to kill it.", ex); } } } }
private async Task OnStop(TimeSpan?timeout) { if (!timeout.HasValue || timeout.Value <= TimeSpan.Zero) { try { _logger.LogInformation($"Killing process {_process.Id}"); _killed = true; _process.Kill(); } catch (Exception ex) { _logger.LogWarning( ex, $"Exception occurred attempting to kill process {_process.Id}. This may if the " + "in the a race condition where process has already exited and an attempt to kill it."); } } else { try { // Signal process to exit. If no response from process (busy or // doesn't support signaling, then this will timeout. Note: a // process acknowledging that it has received an EXIT signal // only means the process has _started_ to shut down. var exited = this.WhenStateIs(State.ExitedSuccessfully); var exitedWithError = this.WhenStateIs(State.ExitedWithError); await CooperativeShutdown .SignalExit(ProcessInfo.Id, _loggerFactory).TimeoutAfter(timeout.Value) .ConfigureAwait(false); await Task .WhenAny(exited, exitedWithError) .TimeoutAfter(timeout.Value) .ConfigureAwait(false); } catch (TimeoutException) { // Process doesn't support EXIT signal OR it didn't respond in // time so Kill it. Note: still a race condition - the EXIT // signal may have been received but just not acknowledged in // time. try { _logger.LogWarning( $"Timed out waiting to signal the process to exit or the " + $"process {_process.ProcessName} ({_process.Id}) did not shutdown in " + $"the given time ({timeout})"); _killed = true; _process.Kill(); } catch (Exception ex) { _logger.LogWarning( ex, $"Exception occurred attempting to kill process {_process.Id}. This may occur " + "in the a race condition where the process has exited, a timeout waiting for the exit," + "and the attempt to kill it."); } } } }