ikeike443のブログ

ソフトウェアビジネスに関心がある系のブログ

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