Event Busを作ってみよう 仕様まとめ（随時更新予定）

# 目的
Pythonでevent-drivenなシステムのコアを作ってみよう。

# Outcome
* Pythonの習熟
    * バックグラウンド処理の実装
* 関数/アプリ間のデータフローの考え方の経験
* 非同期処理に対する理解

# 最終的なイメージ
* event_loop.pyが常に動いている。ここに変更は永遠に加えない
* 開発者はアプリの新規追加・編集・更新が自由に行える。event_loop.pyは変更を自動的に読み込む。
* アプリ間のやり取りはevent_loop.pyを通して行われる
* 各アプリはevent_busから呼び出されるもののあれば、手動で呼び出されるものもある
* 各アプリは非同期的に実行される

# GitHub
https://github.com/shiganai/event_bus

# version集
## version#1
https://qiita.com/shiganai/items/f6dcc53a285bec618ed5

# きっかけ
https://m.youtube.com/watch?v=RfvL_423a-I&pp=ygUYYWF3cyByZWludmVudCBkciB3YXJuZXIg

切り抜き at 0:25:57
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125845/444e9140-cace-c36d-0971-b85424521c7b.png)

~0:50:00までの要約
* 世界はasynchronous(非同期的)
* 非同期処理システムは簡単にアップデートできる(can evolve easily)
    * 新機能の追加
    * スケーラビリティの確保
* ITでもそのようなシステムは単純な機能の組み合わせで複雑な機能が作れる

# 自分の現時点での考え
* 世界が非同期なのはあくまで論理的なイベントを取り扱った場合
    * 郵便が届く、朝ごはんを食べ終わる、電車が駅に着く、などの論理的意味が発生するタイミングのことを論理的なイベントとして書く
    * 論理的なイベントが起こるまで、他のアクションを実行できるという意味で、世界は非同期的
        * AWSの動画で言えば、レストランは時間のかかる料理を調理している間に、サラダなどの盛り付けだけで終わる処理は<時間のかかる料理の開始>という論理的なイベントと<時間のかかる料理の終了>という論理的なイベントの間に終わらせられる。
        * 食戟のソーマという漫画でフランス料理のコースの調理順の過酷さが強調されてたけど、確かに非同期的だと思う
    * ちなみに、運動方程式的に、加速と移動の積分の微小区間を毎回イベントとして捉えれば世界は同期的
        * 2つの自由落下する物体は、その加速方式、その時点での速度に応じた移動量などは常に同期している。
        * 片方の質量が非常に大きかろうと、処理が遅くなって落下するスピードが遅れたりすることはない
* Event-Busはどうしてもシングルスレッド処理の同期処理になっちゃうのでは？
    * Event-Busは軽快に回らないといけない


# 構想 (updated at version #1時点 (branch: release/23_05_13))

tkinterのようなシステムを自分で実装しようと思う。

https://daeudaeu.com/tkinter-update/

より図を抜粋。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125845/af107e6b-2bd9-41aa-9da5-fb7c26826e83.png)

## アルゴリズムイメージ
event_loop.pyのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125845/305df116-ecdc-a345-741f-0eb8a3fc108e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125845/99828d09-3e7c-1510-0808-26a69309f0c0.png)


## ディレクトリ構造

```
event_bus/
|
|- event_loop.py
|- call_apps.py
|- <some other config>
|
|- apps/
    |- dummy_trigger.py
    |- print_event.py
    |- <other apps coming soon>
|
|- new_event_dir/
    |- 2023_05_14_10_21_19_704567_526212028_dummy_trigger.txt (サンプル)
    |- <other apps event coming soon>
|
|- old_event_dir/
    |- 2023_05_13_17_46_05_903853_210209713_dummy_trigger.txt (サンプル)
    |- 2023_05_13_17_46_06_616911_073043986_dummy_trigger.txt (サンプル)
    |- <other apps event coming soon>
|
|- registered_event/
    |- 2023_05_13_18_19_37_203768_158712787.csv (サンプル)
    |- 2023_05_13_18_22_37_302726_415965892.csv (サンプル)
    |- ...
|
|- src/
    |- get_random_int.py
    |- get_absolute_path.py
    |- <other common modules>
|
```

## イベントファイルやトリガー情報ファイルの中身
イベントファイルの例: 2023_05_14_10_21_19_704567_526212028_dummy_trigger.txt
```
1684027279.704568
59944308
dummy
None
```
つまり、
* timestamp: 1684027279.704568
* random int: 59944308
* category: dummy
* path_to_data: None


トリガー情報ファイルの例: 2023_05_13_18_22_37_302726_415965892.csv
```
dummy_trigger,None
print_event,dummy
```
つまり、
* dummy_trigger.pyは"None"というcategoryを持ったイベントが発生したときに呼び出す(Noneというcategoryは禁止ワードにするつもり)
* print_eventは"dummy"というcategoryを持ったイベント(dummy_triggerがそのようなイベントを発生させる)が発生したときに呼び出される




# まとめ
この投稿はアイディア出しなので、どんどん更新していこう。

# 参考サイト
https://note.nkmk.me/python-os-stat-file-timestamp/

https://docs.python.org/ja/3/library/os.html#os.stat_result

https://www.sejuku.net/blog/63568

https://wonderhorn.net/programming/getmtime.html

# 主な更新履歴
* 2023年5月14日 構想をsample#1のものに更新
* 2023年7月17日 最終的なイメージを追記