本来の使い方に即しているかわからないけど、S2Chronosで非同期処理が簡単に実現できる。
前回書いた記事の通りに設定を行った後、リクエストをトリガーにTaskを非同期実行するプログラムを書いた。
package org.seasar.example.action;
import javax.annotation.Resource;
import org.seasar.chronos.core.Scheduler;
import org.seasar.example.task.SampleTask;
import org.seasar.framework.log.Logger;
import org.seasar.struts.annotation.Execute;
public class IndexAction {
private static final Logger logger = Logger.getLogger(IndexAction.class);
@Resource
private Scheduler scheduler;
@Execute(validator = false)
public String index() throws InterruptedException {
// タスク登録
// 登録後、Chronosがプールしている別スレッドで自動実行
scheduler.addTask(SampleTask.class);
// 実行状況を確認するログ出力
for (int i=0;i<10;i++) {
logger.info("アクションの処理実行中 " + i);
Thread.sleep(1000);
}
return "index.jsp";
}
}
package org.seasar.example.task;ブラウザからリクエストを送信した結果が下記。 非同期処理が実現されている。
import org.seasar.chronos.core.annotation.task.Task;
import org.seasar.chronos.core.annotation.task.method.NextTask;
import org.seasar.chronos.core.annotation.trigger.NonDelayTrigger;
import org.seasar.framework.log.Logger;
@Task(autoSchedule=false)
@NonDelayTrigger
public class SampleTask {
@NextTask("test")
public static void doExecute() throws InterruptedException {
// 実行状況を確認するログ出力
for (int i=0;i<10;i++) {
logger.info("タスクの実行中 " + i);
Thread.sleep(800);
}
}
private static final Logger logger = Logger.getLogger(SampleTask.class);
public void initialize() {
logger.info("[initialize]");
}
public void start() {
logger.info("[start]");
}
public void finish() {
logger.info("[finish]");
}
public void destroy() {
logger.info("[destroy]");
}
}
DEBUG 2014-07-13 21:40:30,588 [http-bio-8080-exec-8] BEGIN org.seasar.example.action.IndexAction#index()もちろん自分でスレッド作っても同じだけど、こっちのほうがコード少なくてすむ。
DEBUG 2014-07-13 21:40:30,599 [http-bio-8080-exec-8] トランザクションを開始しました。tx=[FormatId=4360, GlobalId=1405255230598/0, BranchId=]
DEBUG 2014-07-13 21:40:30,599 [http-bio-8080-exec-8] BEGIN org.seasar.chronos.core.impl.SchedulerImpl#addTask(class org.seasar.example.task.SampleTask)
DEBUG 2014-07-13 21:40:30,604 [http-bio-8080-exec-8] END org.seasar.chronos.core.impl.SchedulerImpl#addTask(class org.seasar.example.task.SampleTask) : true
INFO 2014-07-13 21:40:30,604 [http-bio-8080-exec-8] アクションの処理実行中 0
INFO 2014-07-13 21:40:31,604 [http-bio-8080-exec-8] アクションの処理実行中 1
INFO 2014-07-13 21:40:32,604 [http-bio-8080-exec-8] アクションの処理実行中 2
INFO 2014-07-13 21:40:33,605 [http-bio-8080-exec-8] アクションの処理実行中 3
DEBUG 2014-07-13 21:40:33,875 [chronos-pool-3-thread-1] BEGIN org.seasar.example.task.SampleTask#initialize()
INFO 2014-07-13 21:40:33,876 [chronos-pool-3-thread-1] [initialize]
DEBUG 2014-07-13 21:40:33,876 [chronos-pool-3-thread-1] END org.seasar.example.task.SampleTask#initialize() : null
INFO 2014-07-13 21:40:34,605 [http-bio-8080-exec-8] アクションの処理実行中 4
INFO 2014-07-13 21:40:35,605 [http-bio-8080-exec-8] アクションの処理実行中 5
DEBUG 2014-07-13 21:40:35,879 [chronos-pool-1-daemonthread-1] タスク (org.seasar.example.task.SampleTask) を 開始します.
DEBUG 2014-07-13 21:40:35,881 [chronos-pool-1-daemonthread-2] タスク (org.seasar.example.task.SampleTask) を 開始しました.
INFO 2014-07-13 21:40:35,882 [chronos-pool-3-thread-1] [start]
INFO 2014-07-13 21:40:35,886 [chronos-pool-3-thread-1] タスクの実行中 0
INFO 2014-07-13 21:40:36,605 [http-bio-8080-exec-8] アクションの処理実行中 6
INFO 2014-07-13 21:40:36,686 [chronos-pool-3-thread-1] タスクの実行中 1
INFO 2014-07-13 21:40:37,486 [chronos-pool-3-thread-1] タスクの実行中 2
INFO 2014-07-13 21:40:37,605 [http-bio-8080-exec-8] アクションの処理実行中 7
INFO 2014-07-13 21:40:38,286 [chronos-pool-3-thread-1] タスクの実行中 3
INFO 2014-07-13 21:40:38,605 [http-bio-8080-exec-8] アクションの処理実行中 8
INFO 2014-07-13 21:40:39,086 [chronos-pool-3-thread-1] タスクの実行中 4
INFO 2014-07-13 21:40:39,605 [http-bio-8080-exec-8] アクションの処理実行中 9
INFO 2014-07-13 21:40:39,886 [chronos-pool-3-thread-1] タスクの実行中 5
DEBUG 2014-07-13 21:40:40,609 [http-bio-8080-exec-8] トランザクションをコミットしました。tx=[FormatId=4360, GlobalId=1405255230598/0, BranchId=]
DEBUG 2014-07-13 21:40:40,609 [http-bio-8080-exec-8] END org.seasar.example.action.IndexAction#index() : index.jsp
DEBUG 2014-07-13 21:40:40,630 [http-bio-8080-exec-8]
** after *****************************************: /index.do
Response class=org.apache.catalina.connector.ResponseFacade, instance=org.apache.catalina.connector.ResponseFacade@413803ba
[request]indexAction=org.seasar.example.action.IndexAction$$EnhancedByS2AOP$$60223be4@60c0a150
[request]indexActionForm=org.seasar.struts.action.ActionFormWrapper@447cc9c9
[request]javax.servlet.forward.context_path=/s2sample
[request]javax.servlet.forward.request_uri=/s2sample/
[request]javax.servlet.forward.servlet_path=/
[request]org.apache.struts.action.MESSAGE=org.seasar.struts.util.S2PropertyMessageResources@5ca3ce3f
[request]org.apache.struts.action.MODULE=org.seasar.struts.config.S2ModuleConfig@639b99d
[request]org.apache.struts.action.mapping.instance=ActionConfig[path=/index,name=indexActionForm,scope=request,validate=false,cancellable=false
[request]org.seasar.struts.util.S2ExecuteConfigUtil=org.seasar.struts.config.S2ExecuteConfig@37c8f59c
[cookie]JSESSIONID=B594B4C31C8CDCC115905A8A57A739AA
[cookie]JSESSIONID=560C273D113E86C2FED64320DEADF6AB
[session]org.apache.struts.action.LOCALE=ja
INFO 2014-07-13 21:40:40,702 [chronos-pool-3-thread-1] タスクの実行中 6
INFO 2014-07-13 21:40:41,502 [chronos-pool-3-thread-1] タスクの実行中 7
INFO 2014-07-13 21:40:42,302 [chronos-pool-3-thread-1] タスクの実行中 8
INFO 2014-07-13 21:40:43,102 [chronos-pool-3-thread-1] タスクの実行中 9
INFO 2014-07-13 21:40:43,903 [chronos-pool-3-thread-1] [finish]
DEBUG 2014-07-13 21:40:43,904 [chronos-pool-1-daemonthread-2] タスク (org.seasar.example.task.SampleTask) を 終了します.
DEBUG 2014-07-13 21:40:43,905 [chronos-pool-1-daemonthread-2] タスク (org.seasar.example.task.SampleTask) を 終了しました.
DEBUG 2014-07-13 21:40:47,885 [chronos-pool-3-thread-1] BEGIN org.seasar.example.task.SampleTask#destroy()
INFO 2014-07-13 21:40:47,885 [chronos-pool-3-thread-1] [destroy]
DEBUG 2014-07-13 21:40:47,885 [chronos-pool-3-thread-1] END org.seasar.example.task.SampleTask#destroy() : null
また、あまり多くないかもしれないが、契機が時間でなくリクエストとなる(API的な)バッチ処理や、画面からバッチの実行を制御するような場合にはこんな感じで実現すると良さそう。
【環境】
Java SE7Seasar2.4.45
S2Chronos1.0.0