システム開発基盤としてOutSystemsを考えたときに、バッチをどうするか気になると思います。
ここで、OutSystemsを利用している環境でのバッチ実装方法をまとめておきます。
Table of Contents
変更履歴
- 2022/08/16:公式Courseの長時間実行Timerの実装方法ガイドを見つけたので追記
- 2023/02/14:Timerを停止できるように作る を追記
まとめ
Timer:一般的なバッチ
Service Studioを使ってTimerを作るパターン。
OutSystemsでバッチを作ることになった場合は、通常このパターンになります。
作り方
Service StudioでProcessesタブ > Timersフォルダを右クリックし、Add Timerで作成。
時計のようなアイコンがついているのが作成されたTimerです。
ActionプロパティにServer Actionを指定します。このActionがバッチ処理の本体です。
実行方法
- Timerの下に自動で作成されるWake<Timer名> Actionで他のプログラムから任意に起動する(実際はキューを経由するので即始まるわけではない)
- Service Centerで任意に起動する(モジュールを開き、Timersタブから該当Timerを選択。するとRun Nowというボタンが表示されるためこのボタンをクリック)
- 定期実行(Service Studioで開発時にScheduleプロパティに設定するのがデフォルトのスケジュールになる。環境ごとにService Centerで上書きも可能)
注意
タイムアウトがある。デフォルト20分だが延長可能。
タイムアウトすると、処理は中断され、DBはロールバックされる。また、一定時間後に自動でリトライされる(上限回数がある)。
同じTimerは同時に1つしか動作しない。
同時に実行できるTimerには上限値がある。Configuration Toolsで設定可能だがデフォルトは3(サーバーあたり)。
長期間かかる処理にはベストプラクティスで、「処理対象のレコードを小さい単位に分割実行する。分割された単位の実行終了ごとに経過時間を計測し、タイムアウトが近くなったらコミットして自分自身を再実行する(Wake<Timer名> Actionを使う)」ことが勧められている。
(2022/08/16追記)公式Courseの長時間実行Timerの実装方法ガイド
長時間実行するTimerのベストプラクティス(データを一定数で区切って処理し、タイムアウトが近づいたら同じTimerをキューに入れて現在のTimerは終了)の実装方法の解説を含むCourseが公開されていた。
以下の動画と後続のExerciseを見ると、実装方法がわかりやすい。
(2023/02/14追記)Timerを停止できるように作る
Timerは途中で強制終了する仕組みがデフォルトでは備わっていない。
そのため、Site Property等を使って強制終了できるように作っておくのがおすすめ。
Process:人のタスクを含むとき
Process(Service Studio上ではTimerの並びにある)を作るパターン。
単純なバッチではなく、一連の処理の中に非同期に処理を待つ場合や、人のタスクを含む場合に選択する。人のタスクというのは、要するにワークフローです。例えば起票した帳票の承認タスクを課長ユーザーに割り当てる、というようなもの。
進行状況は自動でログが取得され、Service Centerで確認できます。
作り方・実行方法
以前書いたチュートリアルがあります。
注意
Processは長期間動作し続けることになります。そのため、進行中のProcessを含むeSpaceをPublishすることが多くなります。しかし、このときPublishが既存インスタンスに与える影響を分析したり、実行中のプロセスのFlowを更新する処理が走るため時間がかかることがあります。
また、全体としては、非同期に何らかの処理を待つ事ができ長期間動作するのですが、Process中でひとかたまりのバッチ処理を実行するAutomatic Activityは5分でタイムアウトするそうです。
Light Process:Entityレコード追加に対するトリガー
Processの特殊な形態です。Entityの追加イベントを起点にAutomatic Activity1つだけのProcessを動作させることができる。
イメージとしてはデータベースで、テーブルへのレコード追加を起点とするトリガーのようなもの。
作り方・実行方法
これは、以前Qiitaに書きました。
注意
Processだが、Flowに含められるのはAutomatic Activity1つに限られる。つまり単純なバッチしか書けない。
処理の起点はEntityへのレコード追加。
タイムアウトは通常のProcessより短い3分(Outsystems Light Processes Under The Hood)。
進行状況のログは出ない。
外部バッチ
要するに、別のプログラミング言語やETLツール等を使ってバッチを作成することです。
OutSystemsによる開発生産性向上は当然見込めませんが、使い慣れたバッチ開発手法が使える利点があります。
外部DBを使っている場合に向いています。外部DBというのは、OracleやSQL Serverに(OutSystemsとは独立して)存在するテーブルをOutSystemsのEntityとして処理できる方法のことです。
外部DBを使っていない場合、RDBに直接接続してデータを操作することが難しくなるため、REST/SOAPなどの形でデータを渡すI/Fを作ることになります。
非推奨:Expose REST APIを流用
Expose REST APIは実態がServer Actionであり、処理が自由にかけます。更に、動作を観察するとタイムアウトがないかのように見えるので、Server Actionとして作ったバッチ処理にExpose REST APIで呼び出し用I/Fを用意すれば、バッチとして使える、という案です。
なかなか良さそうに見えるのですが、「Expose REST APIにタイムアウトがなく無限に実行を待てる」ということを裏付けるドキュメンがないのと、REST APIはそんなに長時間の処理をするためのものではないため、お勧めできません。
以前Forumにも投稿してみたのですが、やはりドキュメントはないようでした。
Timeout in Exposed REST API Method (Version 10)