Hangfire でジョブ管理

SCOTT HANSELMAN 氏のブログ を見ている方はご存じでしょうが、Hangfire というジョブスケジューラがあります。

GitHub 見てみたら、ロードマップに

Deliver the solution to the 90% of ASP.NET developers :smile:.

とあってとてもほっこりしました。そうだよそういう熱い気持ち、忘れてたよ。。。!

で、ちょうどこういうツールが欲しいってのもあって、興味津々で触ってみました。

基本的な機能

基本的には OWIN Middleware として動く

  • バックグラウンドジョブの登録/更新/実行機能
  • スケジュールジョブの登録/更新/実行機能
  • DashBoard 機能

を行える Web アプリ です。

Web アプリなので Windows サービスやタスクスケジューラなどは不要です。

また、

  • SQL Server, Redis からのジョブストアを選択可能
  • ジョブキューも、ジョブストアのほかに MSMQ, RabbitMQ が選択可能
  • Authorize 機能付き
  • ドキュメントが異常に豊富
  • 専用フォーラム あり

など、バージョン 1.0 としては周辺機能もかなり充実しており、冒頭で紹介したロードマップの本気度がうかがえます。

インストールとジョブの登録

簡単な使い方でも。

インストールは NuGet からです。OWIN を使った Web プロジェクトを作成し、パッケージマネージャコンソールで

Install-Package HangFire

とするだけでインストールされます。

ジョブストアに Redis を使いたかったり、MSMQ などを使いたい場合は HangFire.Redis や、HangFire.SqlServer.MSMQ など必要に応じてパッケージをインストールしてください。

インストールが完了したら、事前準備として OWIN にミドルウェアを登録します。
ロジェクトに Startup.cs ファイルが追加されていると思いますので

public void Configuration(IAppBuilder app)
{
    ConfigureAuth(app);

    app.UseHangfire(config =>
    {
        config.UseSqlServerStorage("your connection string");
        config.UseServer();
    });
}

とセットアップしてやります。

ジョブの登録は専用のクラスからです。

// 単発実行のジョブ
BackgroundJob.Enqueue(() => Console.WriteLine("Execute BackgroudJob."));

// 遅延実行のジョブ
BackgroundJob.Schedule(() => Console.WriteLine("ScheduleJob."), TimeSpan.FromMinutes(1));

// 定期実行ジョブ
RecurringJob.AddOrUpdate("Minutely recurringJob", () => Console.WriteLine("Execute minutely recurringJob."), Cron.Minutely);

// スケジュールされたジョブ
RecurringJob.AddOrUpdate("Cron recurringJob", () => Console.WriteLine("Execute cron recurringJob !!"), "*/2 * * * *");

// 失敗したら自動リトライなんかも出来る
BackgroundJob.Enqueue(() => FailAndRetry());

[AutomaticRetry(Attempts=3)]
public static void FailAndRetry() // public じゃないとエラーになるので注意
{
    throw new Exception("Job Fail !");
}

例えば、これらのコードを Home コントローラの Index アクションメソッドに書いてアプリを実行すると、
画面が開いたタイミングでジョブが登録されます。

ダッシュボードの URL は http://localhost:port/hangfire です。

f:id:kendik:20140903235622j:plain

この状態でしばらく放っておけば、いずれのジョブも実行されます。

f:id:kendik:20140904000402j:plain

ジョブの詳細も見れます。Duration が見れるのは嬉しいですね。

f:id:kendik:20140904000430j:plain:

Recurring Jobs メニューや、Queues メニューからジョブの実行も可能です。

f:id:kendik:20140904001051j:plain

注意すること

調べた限りではありますが、例えば Dashboard のカスタマイズは標準では出来ないみたいです。
Midlleware レベルで HTML 返しちゃってますからね、、、いじるの面倒そう。

まぁ見た感じ単純な API を叩いているだけのようなので、別途 View を作ってやるなりすれば好みの UI にはできると思います。個人的にはちょっと残念ですが。

あとは、ジョブのキャンセルも機能としてはなさそうです。

一応キャンセル用のインタフェースが用意されているのでこれも自分で頑張ればなんとかなるっちゃなりますが、API ないしなぁ。。。 あ、でも、とりあえず止まれば何でもいいならジョブの削除はいつでも出来るので、それで問題のないように作りなさいという話なんでしょうね。

まとめ

プロダクション環境で使うにはあと一歩かゆいところが!な面もありますが、運用タスクとかの実行にはかなりいいんじゃないでしょうか。こういうの欲しかった。ちょっと気に入らないところがあると各自で作り始めたりしますからね、、、チームごとに運用ツールがある、みたいな。面倒な UI とか非同期処理を担ってくれるのはもちろんありがたいですが、これがスタンダードだ!みたいなものが出てきてくれるのは本当に助かります。

更新がかなり頻繁なので(これ書いてる間にバージョン上がった)、多少機能が足りないところもこれから実装されていくかもしれません。ちょうど仕事でバッチの管理ツールが欲しかったので、期待大!です。