きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

Hangfireを使ってみる (6):Jobの種類について:3. Continuations

前回の続きです

今回は3つ目のタイプのジョブについて。

3.Continuations

連続という玉突きというか、指定したJobが終わった後に実行されるように登録するタイプのジョブです。

この前提の話として、前回と前々回で紹介したFire-and-forgetとDelayedを登録するBackgroundJob.EnqueueBackgroundJob.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』にリストアップされていました。

f:id:kiyokura:20170806172032p:plain

Jobテーブル

Jobテーブルはこんな感じです。

f:id:kiyokura:20170808001837p:plain

JobQueueテーブル

JobQueueはこうです。一つ目のジョブのみが登録されています。

f:id:kiyokura:20170808001719p:plain

Setテーブル

Setテーブルを見ると、ここでawaitingで登録されていることが分かります(Valueがジョブid)。

f:id:kiyokura:20170808001347p:plain

JobParameterテーブル

Continuations Jobsの場合のポイントはこのJobParameterテーブルです。JobId=1のレコードの中のName=Continuationsのレコードがあり、後続のジョブのJobIdが記録されていることから、このパラメーターでジョブ同士の関連性を管理しているのでしょう。

f:id:kiyokura:20170808001018p:plain

実行されるときの挙動

Job StorageがSQL Serverの場合、Hangfire Serverによるキューのポーリングを起点に順次実行されます。

このとき、現在キューにあるジョブが読み込まれたタイミングで、ストレージ上に存在する連続するジョブはすべて一度に読み込まれたのち、そのまま連続して処理されるようです。

例えば、ContinueWithで関連付けられたJob1Job2が存在する場合、Job1が実行された後、次回のポーリングを待つことなくそのまま連続して実行されました*1。 ただし、ジョブのステートの遷移を見ると一応は一瞬キューイングされてるようには記録されていますので、内部的には一応キューを経由してるはしているのかも知れません(このあたりソースを読めばはっきりするのでしょうが)。

まとめと次回

Continuations ジョブを利用すると、ちょっとしたバッチ処理のようなことも可能だと思います。ただしBackgroundJob.Requeueメソッドで再実行を行う際には二つ同時にRequeueしても順番の保証はされないようですので*2、その点は注意が必要と思いました

次は 『Recurring』、つまり定期実行タイプのジョブ実行について書きます。

*1:キューのポーリング間隔を十分に長くして検証した結果、そういう挙動が見られました

*2:ダッシュボードで連続するjobを同時に選択してRequeueすると、どちらも同時にQueueに登録された