fix(hosting): exit on our own when the orderly shutdown hangs [CI]
This commit is contained in:
1 parent
839c45c7d4
commit
f9be98e801
1 file changed
+22
@@ -156,6 +156,9 @@ public static class ServiceShell
|
|||||||
log.Info("stopping", ("result", "SIGHUP"));
|
log.Info("stopping", ("result", "SIGHUP"));
|
||||||
cts.Cancel();
|
cts.Cancel();
|
||||||
});
|
});
|
||||||
|
// 有序退出卡住(比如某个已经死掉的会话收不到对端的关闭回复)时不能一直挂着:supervisor 的 stop 超时之前自己退出,由它重新拉起
|
||||||
|
using var exited = new CancellationTokenSource();
|
||||||
|
using CancellationTokenRegistration deadline = cts.Token.Register(() => _ = ExitIfStuckAsync(time ?? TimeProvider.System, log, exited.Token));
|
||||||
Task trimmer = TrimHeapAsync(cts.Token);
|
Task trimmer = TrimHeapAsync(cts.Token);
|
||||||
Task scheduled = restart is null ? Task.CompletedTask : WaitForRestartAsync(restart, time ?? TimeProvider.System, log, cts);
|
Task scheduled = restart is null ? Task.CompletedTask : WaitForRestartAsync(restart, time ?? TimeProvider.System, log, cts);
|
||||||
try
|
try
|
||||||
@@ -171,9 +174,28 @@ public static class ServiceShell
|
|||||||
await cts.CancelAsync();
|
await cts.CancelAsync();
|
||||||
await trimmer;
|
await trimmer;
|
||||||
await scheduled;
|
await scheduled;
|
||||||
|
await exited.CancelAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>退出请求发出之后给有序退出的时间(要短于容器的 StopTimeout,否则 supervisor 会先强杀)。</summary>
|
||||||
|
public static readonly TimeSpan ShutdownGrace = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
|
private static async Task ExitIfStuckAsync(TimeProvider time, INodeLog log, CancellationToken exited)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Task.Delay(ShutdownGrace, time, exited);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
return; // 正常退出了
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Warn("orderly shutdown did not finish in time, exiting", ("grace_s", (long)ShutdownGrace.TotalSeconds));
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task WaitForRestartAsync(RestartController restart, TimeProvider time, INodeLog log, CancellationTokenSource cts)
|
private static async Task WaitForRestartAsync(RestartController restart, TimeProvider time, INodeLog log, CancellationTokenSource cts)
|
||||||
{
|
{
|
||||||
while (!cts.IsCancellationRequested)
|
while (!cts.IsCancellationRequested)
|
||||||
|
|||||||
Reference in new issue
Block a user