前回の続きです
今回は3つ目のタイプのジョブについて。
3.Continuations
連続という玉突きというか、指定したJobが終わった後に実行されるように登録するタイプのジョブです。
この前提の話として、前回と前々回で紹介したFire-and-forgetとDelayedを登録するBackgroundJob.Enqueue
やBackgroundJob.Schedule
メソッドは、戻り値として登録したジョブのidを返します。Continuationsなジョブの登録は、BackgroundJob.ContinueWith
メソッドにそのidを指定して登録することで行います。
例えばこんな感じです。
var jobid = BackgroundJob.Enqueue<MyJobsLib.ICostomJob>(x => x.Execute("Job Executed.")); BackgroundJob.ContinueWith<MyJobsLib.ICostomJob>(jobid, x => x.Execute("2nd job Executed."));
ダッシュボード
上記コードを実行後にダッシュボードをみると、このように『awaiting』にリストアップされていました。
Jobテーブル
Jobテーブルはこんな感じです。
JobQueueテーブル
JobQueueはこうです。一つ目のジョブのみが登録されています。
Setテーブル
Setテーブルを見ると、ここでawaitingで登録されていることが分かります(Valueがジョブid)。
JobParameterテーブル
Continuations Jobsの場合のポイントはこのJobParameterテーブルです。JobId=1
のレコードの中のName=Continuations
のレコードがあり、後続のジョブのJobIdが記録されていることから、このパラメーターでジョブ同士の関連性を管理しているのでしょう。
実行されるときの挙動
Job StorageがSQL Serverの場合、Hangfire Serverによるキューのポーリングを起点に順次実行されます。
このとき、現在キューにあるジョブが読み込まれたタイミングで、ストレージ上に存在する連続するジョブはすべて一度に読み込まれたのち、そのまま連続して処理されるようです。
例えば、ContinueWithで関連付けられたJob1
とJob2
が存在する場合、Job1
が実行された後、次回のポーリングを待つことなくそのまま連続して実行されました*1。
ただし、ジョブのステートの遷移を見ると一応は一瞬キューイングされてるようには記録されていますので、内部的には一応キューを経由してるはしているのかも知れません(このあたりソースを読めばはっきりするのでしょうが)。
まとめと次回
Continuations ジョブを利用すると、ちょっとしたバッチ処理のようなことも可能だと思います。ただしBackgroundJob.Requeue
メソッドで再実行を行う際には二つ同時にRequeueしても順番の保証はされないようですので*2、その点は注意が必要と思いました
次は 『Recurring』、つまり定期実行タイプのジョブ実行について書きます。