[ODC]Event Driven Architectureが発表されたので触ってみる

ODCのEvent Driven Architectureが発表され、すでに利用可能になったので動作確認してみる。

これまでも、Blockには内部で発生した変化を配置先のUIに通知するEventという仕組みがあった。プログラムの観点からは、このEventを、Blockから独立した要素として公開できるようにしたものがEvent Driven Architecture。

# 環境情報
ODC Studio(Version 1.4.0)

# ドキュメント
[Events](https://success.outsystems.com/documentation/outsystems_developer_cloud/building_apps/events/)

# Release Notes
[OutSystems Developer Cloud 2024-03-12のNew](https://success.outsystems.com/support/release_notes/outsystems_developer_cloud_releases/outsystems_developer_cloud/#new_in_outsystems_developer_cloud_2024-03-12)
> It is now possible to publish and consume events between ODC applications. (RRCT-5536)

[ODC Studio 1.4.0のNew in ODC Studio 1.4.0](https://success.outsystems.com/support/release_notes/outsystems_developer_cloud_releases/odc_studio/#new_in_odc_studio_1.4.0)
> It is now possible to publish and consume events between ODC applications. (RDEV-6423)

# 用語
## Event
App内で発生した何らかの変化を表す要素。
ODC StudioのProcessesタブ > Eventsフォルダに作成する。
Eventを発生させた側とは独立に、非同期に発生する（発生側の処理は、Eventの処理を待たずにそのまま続行する）。

## Trigger
Eventを発生させること。
サーバー側のActionから、Trigger Eventという要素を実行することで行う。

## Event Handler
Eventが発生したときに動作するServer Action。
Input Parameterとして、基本データ型とEntity Identifierが使える。

## Subscribe
利用側のAppから、Eventの発生を待ち受ける登録をすること。
Eventに対するEvent Handlerを設定してPublishすることで行う。
ドキュメントによると、この参照は弱い参照。

# チュートリアル
## シナリオ
1. ユーザーが大きなファイルをアップロード
1. アップロードされたファイルを処理する
1. 処理が終わったら、UIに結果を表示する

というシナリオを考える。
このとき、2.のステップに相当時間がかかると、Server Request Timeoutにかかってエラーになってしまう。

そこで、Eventを使ってこの部分を非同期に処理してみる。

作成するサンプルプログラムのイメージは以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/c5fab06d-f348-3455-7cb2-8d89a8bf388a.png)

### ファイル保存Entity
アップロードされたファイルを格納しておくBinaryData Attributeのみを持つEntityを用意しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/0f8ddb6c-166b-501b-0f0a-a37da98eca91.png)

## Event作成
ODC StudioのProcessesタブを開き、Eventsフォルダを右クリック。「Add Event」を選択してEventを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/c346f73b-0ffb-b474-0f3a-7c60a7640934.png)

作成したEventのプロパティ。Name/Description/Publicは他の要素の同名項目と同じ。Handlerには、そのEventが発生したときに動作するServer Actionを設定できる。Server Actionなので同じApp内のものしか設定できない（他のAppからSubscribeするには、Public=Yesにする）。この項目は必須ではない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/310b72a0-c91b-0933-cf01-5b9b5b0439bb.png)

## EventをTriggerする
Eventを発生させるには、サーバー側の処理中でTrigger Event要素を呼び出す。
これまでも、Block内からEventを発生させるときに行っていたのと同じ手順。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/1240cb62-117f-3719-665e-a3dab989cd64.png)


## Event Handler
Eventで定義したInput Parameterを受け取ること以外は、通常のServer Actionとして作成すれば良い。

## ログの確認
①Buttonクリック時に起動されるClient Action
②①から起動されるServer Action（EventをTriggerする）
③Event HandlerとなるServer Action
の開始・終了のタイミングでLog Messageを実行させ、ODC Portal上のLogsを確認した。

### Triggerする側とEvent Handlerは非同期に実行されることが確認できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/64494684-0957-a393-c4e4-c667b8d3d5d7.png)

### 自動で記録されるログ
以下のログが自動でODC Portalに出力されるようだ
- EventがTriggerされたことを示すログ
- EventがHandleされたことを示すログ
- Eventの処理が終了したことを示すログ

## 他のAppからSubscribeできる
他のAppから、Eventを参照して利用することもできる。
その場合は、Consumer側のServer Actionを1つだけHandlerとして指定できた。
なお、LibraryからはEventを参照できなかった。

EventをTriggerさせてみると、ここまでにSubscribe下2つのHandlerが両方動作した。