FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

Playframeworkで定期実行させる - akka-quartz-schedulerを使う

こんにちは、t_hirohataです。

最近PlayFrameworkで、指定した時間に処理を動かすプログラムを書いたので
そこで使ったライブラリをちらっとご紹介します。

akka-quartz-scheduler

今回ご紹介するのは、akka-quartz-schedulerというライブラリで、
cronのような書き方でスケジュールを設定できるというものです。
(※このライブラリはAkkaを使うので、Akkaの知識が多少必要になります。)

このライブラリを使うには、build.sbtに追加する必要がありますが、
Akkaのバージョンによって追加するものが異なるので、こちらを参考に追加すると良いです。

それでは早速使ってみたいと思います!

1.application.confにスケジュールの設定を記述

設定の仕方は簡単で、application.confに以下のように書きます。

akka {
  quartz {
    schedules {
      Every5Seconds {
        description = "5秒毎に実行"
        expression = "*/5 * * ? * *"
      }
      Every10Minutes {
        description = "10分毎に実行"
        expression = "0 */10 * ? * *"
      }
      9o'clockAnd18o'clock {
        description = "JSTの9時と18時に実行"
        expression = "0 0 9,18 ? * *"
        timezone = "Asia/Tokyo"
      }
      EndOfEachMonth {
        description = "JSTの毎月末日の9時に実行"
        expression = "0 0 9 L * ?"
        timezone = "Asia/Tokyo"
      }
    }
  }
}

など、いろいろ設定できます。
expressionにcron形式で書いていくのですが、もっと複雑な設定をしたい場合もあるかと思います。
ここに書き方が載っているので、参考にすると良いです。

2.Actorを用意

akka-quartz-schedulerはAkkaを使っているので、ここでは簡単なActorを用意します

class SampleActor extends Actor {

  def receive = {
    case msg: String => println(msg)
  }

}

3.Globalオブジェクトを用意

今回はアプリケーションをスタートさせた時にスケジュールを実行させるため、
Globalオブジェクトの onStart() メソッドを使って5秒毎に実行するスケジューラーを呼び出します。

object Global extends GlobalSettings {

  val system = ActorSystem("SampleSystem")
  val actor = system.actorOf(Props(classOf[SampleActor]))

  override def onStart(app: Application) = {
    // どのスケジュールを実行するか、どのアクターにメッセージを送信するか、どういうメッセージを送信するかを指定する
    QuartzSchedulerExtension(system).schedule("Every5Seconds", actor, "5秒")
  }

  override def onStop(app: Application) = {
    system.shutdown()
  }

}

4.実行

以上で準備が終わったので、さっそく実行してみましょう!
※ activator run で起動した際、 onStart() メソッドが呼ばれるのは http://localhost:9000 にアクセスしたタイミング。
beforeStart() メソッドも同じタイミングでした。

$ activator run

さて、コンソールを見てみると、実際に5秒毎にメッセージが出力されているのが確認できます。

[info] - play.api.libs.concurrent.ActorSystemProvider - Starting application default Akka system: application
[INFO] [07/11/2015 01:39:44.487] [ForkJoinPool-1-worker-1] [[QuartzScheduler~Sample]] Setting up scheduled job 'EveryFiveSeconds', with 'com.typesafe.akka.extension.quartz.QuartzCronSchedule@c7d42d6'
[info] - play.api.Play - Application started (Dev)
5秒
5秒

5.まとめ

以上のように、akka-quartz-schedulerを使うことで指定した時間に実行するプログラムを作ることができました。

これを使うことで、指定した時間にチャットアプリにメッセージを投稿したり、バッチを実行したりと応用できますね!