4.4 イベントモデル

4.4.1 イベントの種類

これまでの演習では、ASTERIAのフローを実行する方法として、

  • デザイナから実行
  • ウェブブラウザからURLにアクセスしてフローを実行

という2種類の方法で、フローを実行してきました。

しかし、実際にシステムを構築するときには、既存の他システムとの連携や、夜間バッチに使うために毎日フローを起動することなどが必要になってくるはずです。そのたびに人間が手でフローを起動したくはないでしょう。

ASTERIAには、実行設定という便利な機能があり、フローを起動するイベントの管理を行ってくれます。 それでは、実行設定で扱うようなASTERIAのフローを起動する原因になるイベントには、どのようなものがあるのでしょうか。ここでは、大きく3種類に分けてみました。

  • プッシュ型イベント
  • プル型イベント (ポーリング)
  • 定時イベント

それでは、それぞれについて詳しく見ていきましょう。

(1) プッシュ型イベント

このパターンは、他システムがASTERIAの受け口にデータを送信することで、ASTERIAのフローを起動するイベントが発生するパターンです。 この場合には、相手のシステムで起きたイベントを、相手がすぐにASTERIA側に通知してくれるため、リアルタイム性の高い処理が可能です。

他システムからASTERIAにイベントを通知するために、以下の方法が使われます。

  • URL(HTTP)実行設定
  • SOAP実行設定
  • flow-ctrl (コマンドライン)
  • ASTERIA内蔵FTPサーバの受信通知

プッシュ型イベントでは、ASTERIAは受動的(パッシブ)に待ち受けるだけなので、難しいことを考える必要はありません。 必要なのは、実行設定で待ち受け口を用意しておくだけです。

(2) プル型イベント (ポーリング)

このパターンは、ASTERIAが他システムを常時監視して、更新されたデータを受信することで、ASTERIAのフローで処理を実行するイベントを発生させるパターンです。 監視対象になる更新イベントには、以下のようなものがあります。

  • ディレクトリに新規ファイルが置かれたとき
  • FTPサーバに新規ファイルが置かれたとき
  • メールボックスに新規メールが届いたとき
  • RDBのデータが更新されたとき

この場合には、相手のシステムで起きるデータ更新イベントをASTERIA側から能動的(アクティブ)に監視するので、そのためのポーリングフローを作って定期的に呼び出すようにスケジュール実行設定をする必要があります。

ポーリングフローの作り方は、後で詳しく取り上げます。

(3) 定時イベント

このパターンは、ASTERIAのスケジューラが定期的にフローを起動するパターンです。 この場合には、他システムを監視するという明確な目的を持ったポーリングの場合と異なり、もっと別の目的で定期起動されるようなものを想定しています。

ASTERIAフローを定期的に起動するために、プル型イベントの場合と同様にスケジュール実行設定が使われます。

4.4.2 定時バッチとポーリング

(1) 定時バッチとポーリングの違い

ここでは定時バッチとポーリングの違いについて、もう少し掘り下げて考えてみましょう。

定時バッチとポーリングは、一定時間ごとにフローを実行するという意味では違いはありませんが、実行するフローの性質が大きく異なります。その違いをまとめたのが、以下の表です。

定時バッチ ポーリング
起動間隔 1日〜1週間と長い 1分〜1時間と短い
処理時間 数分〜数時間 数秒
処理データ量 一度に大量のデータを処理 イベントに応じて少しずつリアルタイムに処理

ここで注目したいのが、起動間隔と処理時間の違いです。

定時バッチは、一般的には定期的に起動するジョブですが、そのかなりの部分を占めるのは夜間の数時間を利用してジョブを実行するいわゆる「夜間バッチ」でしょう。

夜間バッチの場合は、必ず朝には処理が終わるので、前のジョブが完了しないうちに次のジョブが走り出すことはまずあり得ません。つまり、複数のジョブが同時に実行される状況、つまり並行性を考慮することは、ほとんど必要ないでしょう。

一方、ポーリングの場合には、すぐに実行が終わるジョブを短い時間間隔で繰り返し実行するという特性があります。 そのため、大量のデータを一気に投入した場合には、ジョブの実行に時間がかかってしまい、先発のジョブが終了する前に、後発のジョブの実行が始まってしまう場合が十分にあり得ます。つまり、複数のジョブが同時に実行される可能性が比較的高いので、フローを設計するときには並行性を常に考慮する必要があるということです。

(2) ポーリングフローの並行制御

ここまでの議論で、ポーリングフローを構築するときには、並行性を考慮する必要があることがわかりました。この節では具体例を題材に、フローでの並行制御の方法と、スケジュール実行の時間間隔の決定方法を考えていきます。

ここでは、以下のメールボックスのポーリングフローを題材に、これらの問題について考えていきましょう。

このフローで行っている処理は、以下のような流れになっています。

Component Tab Description
(1) Mutex Control 同時実行数を1に制限(排他制御)する
(2) POP3 Network メールボックスのメールを全件取得する
(3) MIMEDecode Format メールの本文を取得する
(4) Mapper Control メールの内容をレコードに変換する
(5) RDB(Put) Storage レコードをRDBに保存する
(6) End Control フローの終了後、POP3コンポーネントは読み出したメールをすべて削除する
ポイントは、フローの開始直後に Mutexコンポーネントを使っているところです。 Mutexコンポーネントは、排他制御を行うコンポーネントで、Mutexコンポーネントからフロー終了までの間の処理を、同時に1つしか実行されないようにする効果があります。

つまり、このフローを複数同時に実行したとしても、後発のフローは Mutexコンポーネントのところで待ち状態になり、先発のフローがすべての処理を完了してから、後発のフローが Mutexコンポーネントのところから実行を始めることになります。

このように、Mutexコンポーネントで排他制御を行うことは、並行制御のもっとも有効な解決策です。複数のフローが同じリソースを読み書きすることは、予想以上に複雑な問題(トランザクションのACID問題)を引き起こすことが知られています。そのため、排他制御を行うことで並行性の問題を避けることが、もっともわかりやすく失敗の少ない解決策だと言えるのです。

(3) ポーリング間隔の決定

ここまでで、ポーリングフローを構築することができました。 次は、このポーリングフローをどのくらいの間隔で呼び出すようにスケジュール設定するかを決めなければいけません。

スケジュール間隔は、あまり長いとポーリングのリアルタイム性が失われてしまいます。すぐ処理したいメールが、何時間も経ってから処理されても困るでしょう。 かといって、あまり短く設定すると、フローでメールを処理している間に、どんどん後続のフローが起動され、Mutexコンポーネントの箇所でたくさんのフローが渋滞してしまうことになります。

何事も行き過ぎはよくないということでしょうか。 素早く処理したいけれど、素早すぎると渋滞を引き起こすというジレンマ。これを解決するためには、MutexコンポーネントのTimeoutプロパティを使うという方法があります。

MutexコンポーネントのTimeoutプロパティは、デフォルトで「0」に設定されているため、先発のフローが実行されている場合には永遠に待ち続けます。しかし、ここに「0」以外の値を設定してやることで、その秒数の間だけ待っても実行が開始できないときには、例外を出して処理を中断するようにできます。

例えば、ここに「5」を設定してやることで、後続のフローが5秒待っても先発のフローが終了しないときには、例外を出してあきらめるようになります。

その結果、かなり短い間隔でスケジュール設定しても、Mutexでたくさんの順番待ちフローが渋滞することは起こらなくなります。

最後に、このフローをスケジュール実行設定で、短い間隔(例えば1分)で定期実行するように設定しておけば、メールボックスのポーリング処理の完成です。

(4) ポーリングフロー設計のまとめ

ここまでで、メールボックスをポーリングする仕組みが完成しました。 要点をまとめると、

  • フローは排他制御から始める
  • MutexコンポーネントのTimeoutプロパティを小さい値にする
  • スケジュール実行設定で、短い間隔でフローを定期実行するように設定する

ということになります。

さて、今回はメールボックスのポーリングを例として取り上げました。 ポーリングしたいのは、メールサーバばかりではないでしょう。 他の種類のリソースをポーリングする場合には、注意すべきことがあります。

それは、フローでデータを読み出すときに、書き込み途中のデータを読み込んでしまう危険性です。 幸いなことに、RDBと多くのメールサーバはトランザクション化されているので、フローでデータを読み出すときに、書き込み途中のデータが混入することはありません。

しかし、ローカルディレクトリとFTPディレクトリを監視する場合には、新規に作成されたファイルが書き込み途中である可能性を考慮する必要があります。 どちらの場合にも、まずファイルの一覧を取ってすべてのファイルについて処理をすることになりますが、ファイルの一覧を取ったときに書き込み途中のファイルが一覧に入っていると、書き込み途中のファイルを処理してしまうことになり、非常に危険です。 したがって、ローカルディレクトリとFTPディレクトリを監視する場合には、この問題を回避するための特別な仕組みが必要になります。

4.4.3 実行設定

ASTERIAの実行設定は、フローを起動する手段を3つ提供しています。

  • URL(HTTP)
  • SOAP
  • スケジュール

ここでは、それぞれの実行設定の使い方、設定方法を見ていきましょう。

(1) URL(HTTP)

ASTERIAサーバはウェブサーバを内蔵しており、普通のウェブサーバと同じように、ウェブブラウザからサーバ上のコンテンツにアクセスするできるようになっています。 それに加えて、フローをURLに関連づけてやる、ウェブブラウザでURLにアクセスするとフローを実行してその結果を返すこともできます。これが、URLの実行設定です。

「ウェブアプリケーションを作ってみよう」の項では、実際にURLの実行設定を使って、簡単なウェブアプリケーションを構築しました。このような、ウェブアプリケーションの他には、HULFTやJP1などの他のアプリケーションとHTTP経由で連携するときに、この機能を利用できるでしょう。

URLの実行設定は、以下の手順で設定します。

ツールバーの「実行設定」アイコンをクリックします。

「実行設定」ダイアログが表示されます。

「Flow」の項目をクリックし、URLに関連づけるフローを選択します。

「Type」の項目はデフォルトで「URL」が選択されているので、「URL / MethodName / Schedule」の項目をクリックして、フローに関連づけるURLを入力します。

OKボタンを押して、実行設定を終了しましょう。

このように設定すれば、URLにウェブブラウザでアクセスすると、フローが実行されるようになります。

(2) SOAP

実行設定の「Type」に「SOAP」を選択することで、フローをRPC型のSOAPウェブサービスとして公開することができます。

この実行設定は、他のプログラミング言語やツールなどを用いて、SOAPクライアントを作り込む必要があります。従って、手間がかかるため、実際に利用することはかなり少ないでしょう。

(3) スケジュール

スケジュールの実行設定では、フローを定期実行することができます。 この機能を使うことで、定時イベントとポーリングを実現することができます。

スケジュール実行設定の方法は、以下のようになっています。

まず「実行設定」ダイアログで、「Type」の項目から「スケジュール」を選択します。

「URL / MethodName / Schedule」の項目をクリックすると、「スケジュールの設定」ダイアログが開きます。

「繰り返し設定」の項目で、スケジュールの実行間隔を設定します。 たとえば、ここでは「毎日」を選択しました。

そして、他の設定項目に値を設定していけば、スケジュールの実行設定は完了です。

この例では、毎日午前2時に実行される夜間バッチのスケジュール設定を行いました。

4.4.4 その他のフローの実行方法

(1) flow-ctrl(コマンドライン)

ASTERIAサーバには、flow-ctrlというコマンドラインのツールが付属しています。 flow-ctrlを利用することで、コマンドラインから簡単にフローを起動して実行結果を取得することができます。 URL(HTTP)を使えないような場合には、フローを実行する有力な手段になるでしょう。

詳しい使い方は、管理コンソールにログインして、メニューから「ヘルプ」→「ヘルプリンク」→「flow-ctrlの使い方」のページに記載されていますので、そちらを参照してください。

(2) FTPサービスのURL通知

ASTERIAサーバはFTPサーバを内蔵しており、クライアントからのファイルを受信完了したときに、ファイル名をURL通知する機能があります。 この機能を利用することで、ファイルの受信と同時にフローを起動して、受信したファイルを処理することができます。

詳しい使い方は、ASTERIA Users Guideの「12.7 FTPサービス」の項を参照してください。