きなこもち.net

.NET Framework × UiPath,Orchestrator × Azure × AWS × Angularなどの忘備録

dotent × worker service × ゾンビ化を防ぎたい

Goal

doent worker serviceでBackgroundServiceから予期せぬエラーがスローされたときの挙動を理解して、ゾンビ化しないようにしたい。

.NET 6以前の挙動

BackgroundServiceからスローされた例外は、Hostサービスに無視されていた。そのため、予期せぬエラーが発生した場合、BackgroundServiceはKillされるが、Hostサービスは何事もないように動き続けるふるまいを見せた。
これにより、あたかも正常に動作を続けているように見えて、実は何もしていないという状態が作り出されていた。=Worker serviceのゾンビ化。

.NET 6移行の挙動

BackgroundServiceで予期せぬエラーが発生した場合のHostサービスのふるまいを定義するための列挙型が新設された。
BackgroundServiceExceptionBehavior
この列挙型には、2つの定義がある。 - Ignore - StopHost (Default)
このうち、Ignoreは、.NET 6以前の挙動と同じふるまいになるように定義するものである。
もう一つのStopHostは、同様の現象が発生したとき、Hostサービス自体を安全に停止するふるまいを定義するもので、.NET 6以降では、デフォルトのふるまいである。
このふるまいの設定は、ServiceのConfigureをするときに設定することができる。

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddHostedService<Worker>();
        services.Configure<HostOptions>(HostOptions =>
        {
            HostOptions.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore;
        });
    })
    .Build();

二つのBackgroundServiceを定義したとき。Worker Aから予期せぬエラーがスローされた場合。

Ignoreの場合

Worker AはKillされ、その後は何もしない。一方、Worker Bは、そのまま実行を続ける。

StopHostの場合

HostサービスがWorker Aのエラーを検知し、Hostサービスを停止する。この時、ほかのサービスには、cancellationTokenが発行されて順次停止する。

References