Linuxのsystemdでworkerアプリを動かして、systemctlコマンドで安全に開始・停止出来るようにするには、workerプロジェクトにMicrosoft.Extensions.Hosting.Systemdパッケージを追加して、Windowsサービスの時と同じように、UseSystemd()を追加する。
public class Program
{
・・・
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
以下のようなSystemd用のサービス定義ファイルを作成。
[Unit]
Description=Worker Test on Linux Systemd
[Service]
Type=notify
WorkingDirectory=<作業ディレクトリ>
ExecStart=/usr/bin/dotnet <DLLのPATH>
[Install]
WantedBy=multi-user.target
サービスタイプをnotifyとする。
後は、systemctlでサービスを登録して、起動・停止が可能。
systemctl enable <サービス名>.service
systemctl start <サービス名>
systemctl stop <サービス名>
実際に動かしてログをみてみると
MMM DD HH:mm:ss exodus-v12 systemd[1]: Starting Worker Test on Linux Systemd...
・・・
MMM dd HH:mm:ss exodus-v12 <サービス名>[nnnnn]: <プロジェクト名>.Worker[0] Worker running at: MM/dd/YYYY HH:mm:ss +09:00
MMM dd HH:mm:ss exodus-v12 <サービス名>[nnnnn]: <プロジェクト名>.Worker[0] Worker running at: MM/dd/YYYY HH:mm:ss +09:00
MMM dd HH:mm:ss exodus-v12 systemd[1]: Stopping Worker Test on Linux Systemd...
MMM dd HH:mm:ss exodus-v12 <サービス名>[nnnnn]: Microsoft.Hosting.Lifetime[0] Application is shutting down...
MMM dd HH:mm:ss exodus-v12 systemd[1]: <サービス名>.service: Succeeded.
MMM dd HH:mm:ss exodus-v12 systemd[1]: Worker Test on Linux Systemd.
systemctl stopを実行した時点でworkerプロセスに通知されている様子が分かる。
ただし、workerスレッドの実行ブロックループの後にログを出力させても、そのログが出力されていないので、workerスレッドの上位で終了処理を行っているように思える。
この辺りかな?
https://docs.microsoft.com/en-us/dotnet/core/extensions/generic-host
もっと簡単でした。
https://docs.microsoft.com/en-us/dotnet/core/extensions/workers
などを見ると、Task.Delay等で、”A task was canceled.”例外が起こるようです。