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();
        }
Example #2
0
        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();
        }
Example #3
0
        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);
                    }
                }
            }
        }
Example #4
0
        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.");
                    }
                }
            }
        }