about jobs

40
About Jobs

Upload: shinichi-kozake

Post on 24-May-2015

743 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: About Jobs

About Jobs

Page 2: About Jobs

Who?

s_kozake(小酒信一)

I’m Java Programmer

Page 3: About Jobs

こんな心意気で頑張っております

Javaは亡びぬ何度でも蘇るさ!!Javaは亡びぬ何度でも蘇るさ!!

JVMの力こそプログラマーの夢だからね。。誰だ?今「バルス」とかいった奴

Page 4: About Jobs

About Jobs

Page 5: About Jobs
Page 6: About Jobs

の話じゃありません

Page 7: About Jobs

play.jobs.*

のお話です。

Page 8: About Jobs

Playにジョブ管理機能があるのご存知でした?

Page 9: About Jobs

Playのジョブ管理は結構便利です!!

Page 10: About Jobs

起動時に実行するジョブpackage jobs;

import play.*;import play.jobs.*; @OnApplicationStartpublic class Bootstrap extends Job { public void doJob() { Logger.info("=== Application start ==="); } }

Page 11: About Jobs

@OnApplicationStart(async=true)

とすると、バックグラウンドで実行できます

Page 12: About Jobs

スケジューリングされたジョブ

package jobs;

import play.*;import play.jobs.*; @Every("10s")public class EveryTenSeconds extends Job { private int count = 0; public void doJob() { count++; Logger.info("=== EveryTenSeconds execute " + count + "time" + (count > 1 ? "s" : "")); } }

Page 13: About Jobs

10日毎 ・・・ @Every("10d")10時間毎 ・・ @Every("10h")10分毎 ・・・ @Every("10mn")       or @Every("10min")10秒毎 ・・・ @Every("10s")

Page 14: About Jobs

PlayはCRON式もサポートしています。

Page 15: About Jobs

CRON式でスケジュールされたジョブ

package jobs;

import play.*;import play.jobs.*;import java.util.Calendar; @On("2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59 * * * * ?")public class EveryPrimeNumber extends Job {

public void doJob() { Logger.info("=== Every prime sec " + Calendar.getInstance().get(Calendar.SECOND) + " execute " ); } }

Page 16: About Jobs

* * * * * ? *秒

(0-59 *)時間(0-23 *)

日(1-31 * ?)

月(1-12 * ?)

or(JAN-DEC)

曜日(1-7 * ?)

or(SUN-SAT)

年(1970-2099 *)

[option]

分(0-59 *)

CRON式(基本)

@On(“ 2 * * * * ?”)・・・毎分2秒に実行@On(“ 0 0 * * * ?”)・・・毎時0分に実行@On(“30 59 23 * * ?”)・・・毎日23:59:30秒に実行@On(“30 59 23 ? * 2”)・・・毎金曜日の23:59:30秒に実行

Page 17: About Jobs

CRON式(応用)

@On(“0,30 * * * * ?”)・・・毎分0,30秒に実行@On(“30 10-20 * * * ?”)・・毎時10~20分の間、30秒に実行@On(“5/15 * * * * ?”)・・・毎分5秒から15秒毎(5,20,35,50)に実行

各項目には(, - /)を指定できます。

Page 18: About Jobs

CRON式(さらなる応用)

日のLは月の最終日。曜日のLは月の最後の曜日。@On(“0 23 59 L * ?”)・・・毎月の最終日(1月なら31日、4月なら30日)の23:59:00に実行@On(“0 23 59 ? * 6L”)・・・毎月の最後の土曜日に実行

日のWは一番近い月~金曜日。例えば、15Wは15日が土曜日なら、14日の金曜日に実行。15日が日曜日なら16日の月曜日に実行。15日が火曜日なら、15日火曜日に実行。1Wは1日が土曜日なら、3日の月曜日に実行

曜日の#は月の何番目の曜日か。例えば、6#3は月の3回目の金曜日。

日には(L W)、曜日には(L #)を指定できます。

Page 19: About Jobs

CRON式を環境変数に記述可能package jobs;

import play.*;import play.jobs.*;import java.util.Calendar; @On("cron.everyprimenumber")public class EveryPrimeNumber extends Job {  :

cron.everyprimenumber=2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59 * * * * ?#cron.everyprimenumber=never

application.conf

“cron.”で始まるものは環境変数と認識される

neverを設定すると、実行されませんよ

Page 20: About Jobs

トリガータスクジョブ

public static void encodeVideo(Long videoId) { new VideoEncoder(videoId).now(); renderText("Encoding started");}

nowメソッドで即時実行できます。戻り値は予約オブジェクトで受け取れます。

Page 21: About Jobs

NOTE

DEV モードでアプリケーションを実行する場合、アプリケーションは最初の HTTP リクエストがあるまで始動を控えます。さらには、DEV モードの場合、アプリケーションは必要に応じて自動的に再起動することがあります。

PROD モードで実行するとき、アプリケーションはサーバの起動と同時に開始します。

Page 22: About Jobs

実演

Page 23: About Jobs

Inside of Play.jobs

Page 24: About Jobs

@EveryはScheduledThreadPoolExecutorのscheduleWithFixedDelayメソッドで実現している。

@Onはタスク終了後にcron式の次の日付を求めて、 duledThreadPoolExecutorのscheduleメソッドを毎回読んでいる。

play.jobsはjava.util.concurrentの機能を色々使ってて、勉強になるお

Page 25: About Jobs

About cron4j

Page 26: About Jobs

cron4jってご存知ですか?

Page 27: About Jobs

Javaでunixのcrontabを使えます!

Page 28: About Jobs

MyTask.java

public class MyTask implements Runnable {

public void run() {

System.out.println("Current system time: " + new Date());

System.out.println("Another minute ticked away...");

}

}

Quick Start

タスクを書いて。。

Page 29: About Jobs

public class Main {

public static void main(String[] args) {

MyTask task = new MyTask();

Scheduler scheduler = new Scheduler();

scheduler.schedule("* * * * *", task);

scheduler.start();

try {

Thread.sleep(5L * 60L * 1000L);

} catch (InterruptedException e) {

;

}

scheduler.stop();

}

}

Main.java

スケジューラを起動するだけ。。

Page 30: About Jobs

ファイルも扱えます

Page 31: About Jobs

public class Main {

public static void main(String[] args) {

Scheduler scheduler = new Scheduler();

scheduler.scheduleFile("* * * * *", new File("cron4jtab.txt");

scheduler.start();

:

Main.java

こんな感じ

Page 32: About Jobs

0 5 * * * sol.exe

0,30 * * * * OUT:C:\ping.txt ping 10.9.43.55

0,46 * * * * "OUT:C:\My Folder With Spaces\ping.txt" ping 10.9.43.55

0 3 * * * ENV:JAVA_HOME=C:\jdks\1.4.2_15 DIR:C:\myproject OUT:C:\myproject\build.log C:\myproject\build.bat "Nightly Build"

0 1 * * * java:test.TestClass#testMethod "Iron Maiden" "Megadeth" "Black Sabbath" "Led Zeppelin" "Blind Guardian"

cron4jtab.txt

ファイルの中身。Javaメソッド単位で起動することも、外部プロセスを起動することも可能。Javaの場合、class#method の形式のメソッドを呼び出し可能メソッドはstaticでString配列をパラメータで受け取れること。記述を省いた場合、main(String[] args)が呼ばれます。

外部プロセスを呼び出す場合、 OUT・・標準出力 IN・・・・標準入力 ENV・・環境設定 DIR・・・作業フォルダが指定可能です。

ファイルの中身はスケジューラ実行中にも変更可能&反映されます。

Page 33: About Jobs

Taskの状態を制御したり、監視したりできます。

Page 34: About Jobs

public class MyTaskExecutorListener implements TaskExecutorListener {

public void executionPausing(TaskExecutor executor) {

System.out.println("Task pausing!");

}

public void executionResuming(TaskExecutor executor) {

System.out.println("Task resuming!");

}

public void executionStopping(TaskExecutor executor) {

System.out.println("Task stopping!");

}

public void executionTerminated(TaskExecutor executor, Throwable exception) {

System.out.println("Task terminated!");

}

public void statusMessageChanged(TaskExecutor executor, String statusMessage) {

System.out.println("Task statusMessage = ["+statusMessage+"]");

}

public void completenessValueChanged(TaskExecutor executor, double completenessValue) {

System.out.println("Task completeness["+completenessValue * 100+"]%");

}

}

MyTaskExecutionListener.java

Page 35: About Jobs

import it.sauronsoftware.cron4j.SchedulerListener;

import it.sauronsoftware.cron4j.TaskExecutor;

public class MySchedulerListener implements SchedulerListener {

public void taskLaunching(TaskExecutor executor) {

System.out.println("Task launched!");

executor.addTaskExecutorListener(new MyTaskExecutorListener());

}

public void taskSucceeded(TaskExecutor executor) {

System.out.println("Task completed!");

}

public void taskFailed(TaskExecutor executor, Throwable exception) {

System.out.println("Task failed due to an exception!");

exception.printStackTrace();

}

}

MySchedulerListener.java

Page 36: About Jobs

import it.sauronsoftware.cron4j.Scheduler;

public class Main {

public static void main(String[] args) {

MySchedulerListener listener = new MySchedulerListener();

MyTask task = new MyTask();

Scheduler scheduler = new Scheduler();

scheduler.addSchedulerListener(listener);

:

}

}

Main.java

Page 37: About Jobs

import it.sauronsoftware.cron4j.Task;

import it.sauronsoftware.cron4j.TaskExecutionContext;

public class MyTask extends Task {

public boolean canBePaused() { return true; }

public boolean canBeStopped() { return true; }

public boolean supportsCompletenessTracking() { return true; }

public boolean supportsStatusTracking() { return true; }

public void execute(TaskExecutionContext context) throws RuntimeException {

for (int i = 1; i <= 30; i++) {

System.out.println("Task says: " + i);

context.setStatusMessage("i = " + i);

context.setCompleteness(i / 30D);

try {

Thread.sleep(1000);

} catch (InterruptedException e) { ; }

context.pauseIfRequested();

if (context.isStopped()) {

break;

}

}

}

}

MyTask.java

Taskの状況メッセージを設定

Taskの進捗を設定

ポーズ要求がある場合はwait

停止要求がある場合は終了

Page 38: About Jobs

ジョブの画面制御も簡単

Page 39: About Jobs

・スケジュールは分単位まで

play.jobsとちゃうとこ

・前のタスクが終わらんでも、次が動く

・タスクは毎回newされるから、状態もてない

・Java2から使える

Page 40: About Jobs

Thank You!