PlayframeworkのJobをOn/Offしたい
Play!では簡易的なジョブフレームワークがある。
play.jobs.Jobを継承して、@Everyか@Onといったアノテーションを書いておくと、それにしたがってスケジュール実行してくれる。
アノテーションの中はCronとほぼ同じ書式。正確にはこっちね。
で、こいつのOn/Offを設定ファイルなどでハンドル出来ないかなーと思ってコードを読んでみた。
以下はそのメモ。
サーバ起動後、JobsPlugin#afterApplicationStartが呼ばれる。下記はEveryアノテーションの部分を抜粋。基本的にOnも一緒。
// @Every if (clazz.isAnnotationPresent(Every.class)) { try { Job job = (Job) clazz.newInstance(); scheduledJobs.add(job); String value = ((Every) (job.getClass().getAnnotation(Every.class))).value(); if (value.startsWith("cron.")) { ←ココ value = Play.configuration.getProperty(value); ←ココ } executor.scheduleWithFixedDelay(job, Time.parseDuration(value), Time.parseDuration(value), TimeUnit.SECONDS); } catch (InstantiationException ex) { throw new UnexpectedException("Cannot instanciate Job " + clazz.getName()); } catch (IllegalAccessException ex) { throw new UnexpectedException("Cannot instanciate Job " + clazz.getName()); } }
上記のように、cronで始まるアノテーションがあった場合、confファイルから値を取ってくるように動いている。
ので、スケジュールの設定はapplication.confに書いておけばいいようだ。ジョブごとに設定を変えたいなら、
cron.JobA=5min cron.JobB=* 0 * * * ?
みたいに書いておけばいい。
が、ジョブをOn/Offする機構はない模様。
試しに0minとかしてみたが、例外吐きました。。
executor.scheduleWithFixedDelay(job, Time.parseDuration(value), Time.parseDuration(value), TimeUnit.SECONDS);
ってところで呼ばれてるjava.util.concurrent.ScheduledThreadPoolExecutorのコード見ると、下記のようになってるのでまあしょうがないかな。。
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { if (command == null || unit == null) throw new NullPointerException(); if (delay <= 0) throw new IllegalArgumentException(); if (initialDelay < 0) initialDelay = 0; long triggerTime = now() + unit.toNanos(initialDelay); RunnableScheduledFuture<?> t = decorateTask(command, new ScheduledFutureTask<Boolean>(command, null, triggerTime, unit.toNanos(-delay))); delayedExecute(t); return t; }
んーむり。一応コミュニティに質問と要望はだしておくか。。
質問を投げたところ、Guillamueから返事きた。パッチ送ってくれとのことなので、余裕があれば送るかも。。
http://groups.google.com/group/play-framework/browse_frm/thread/8ab15a27eec68814