Slide 1

Slide 1 text

qmuntal/stateless のススメ Go Connect #3 2024.10.23

Slide 2

Slide 2 text

自己紹介 Sugar Sato (@satoIsSugar) ● 2023年 BuySell Technologies入社 ● 基盤チーム所属(Portal/Account/Approval) PjM ○ アソシエイトマネージャー ● Go / Angular / Serverless ○ Go歴: Go 年目くらい ● 熱帯植物 ○ ビカクシダ ● 猫 ○ Lambda (♀ 2才)

Slide 3

Slide 3 text

プロダクト群「バイセルリユースプラットフォーム Cosmos」の開発が進行中 リユースに必要なすべての機能を提供する 「リユースプラットフォーム Cosmos」の開発が進行中です。 Cosmosを活用して、バイセルグループ全体での業務効率改善やデータドリブン経営の深化を目指しています。 リユースプラットフォーム Cosmos 自社開発のリユース特化業務基幹システムでありサービス群の集合体 買取申込 買取・査定 在庫管理 販売 多様なチャネルで収益最大化 CRM -顧客対応- 買取種別に応じた最適なシステム構築 Visit -訪問買取 - Store -店舗買取 - Promas -商材マスタ - Appraisal -専門査定 - Stock -在庫管理 - EXS -販売管理 - Core -会員管理- Portal -データ利用- Pocket -データ基盤- 買取 専門チームによる真贋・査定と連携 査定 申込 効率的な顧客対応 在庫 在庫管理の最適・効率化 販売 データ 各事業プロセスにある データを一元管理 :基幹システム

Slide 4

Slide 4 text

アジェンダ ステートマシンとは 01 ステートマシン導入背景 02 まとめ 04 qmuntal/stateless とは 03

Slide 5

Slide 5 text

ステートマシンとは

Slide 6

Slide 6 text

みなさんは ステートマシンって知っていますか?

Slide 7

Slide 7 text

● 状態遷移を表現するための理論モデル ○ ゲームや組み込みなどで使われてきた技術 ■ 「キャラクターにどのようなアクションをさせるか」 ○ サービス ■ AWS: Step Functions ■ GoogleCloud: Workflows ステートマシン

Slide 8

Slide 8 text

ステートマシン

Slide 9

Slide 9 text

ステートマシン導入背景

Slide 10

Slide 10 text

● 決裁サービス開発でステータス管理が必要 ○ どんなイベントがきても不具合を起こしにくくしたい ○ 新しく「状態」を追加することを簡単にしたい ○ 状態遷移に漏れがないか気が付きやすくしたい ○ テストパターンもシンプルにしたい 導入背景

Slide 11

Slide 11 text

導入するにあたって Go だと どんなステートマシンがあるだろうか、、、

Slide 12

Slide 12 text

技術選定 スター数 リリース 特徴 qor/transition 433 v1.1.0 (2019/04/23) GORMと統合 状態変化ログの自動 保存 bykof/stateful 209 v0.0.8 (2020/05/24) 構造体を作って stateful インター フェースを実装する looplab/fsm 2,830 v1.0.2 (2024/05/16) 他言語ステートマシ ンライブラリに触発さ れている ※ 2024/10/16 現在

Slide 13

Slide 13 text

● 不採用 ○ GORM との相性がよい ■ b.c. コミッターに jinzhu san ○ 最後のリリースから早5年... ○ [IMO] 状態遷移のコードが若干見づらいかも 技術選定 (qor/transition)

Slide 14

Slide 14 text

技術選定 (qor/transition)

Slide 15

Slide 15 text

● 不採用 ○ 構造体を作って stateful インターフェースを実装する ○ 状態は文字列で定義する ○ 最後のリリースから早4年... ○ graphviz を使ってグラフ化できる 技術選定 (bykof/stateful)

Slide 16

Slide 16 text

技術選定 (bykof/stateful)

Slide 17

Slide 17 text

技術選定 (bykof/stateful)

Slide 18

Slide 18 text

● 不採用 ○ 他言語のステートマシンライブラリに触発されている ■ oxplot/fysom, jakesgordon/javascript-state-machine ○ [IMO] 若干使い勝手が悪く感じた ■ fsm.Events 内が全て string 型のため ● 定数が扱えない ■ 既存のパラメータに対して fsm を合成する必要がある 技術選定 (looplab/fsm)

Slide 19

Slide 19 text

技術選定 (looplab/fsm)

Slide 20

Slide 20 text

選択肢のなかだと looplab/fsm がよさそうだけど より使いやすそうなステートマシンはないかな ...

Slide 21

Slide 21 text

「さらに便利なステートマシンをもとめ 我々はアマゾンの奥地へ向かった ――」

Slide 22

Slide 22 text

qmuntal/stateless とは

Slide 23

Slide 23 text

● > Create state machines and lightweight state machine-based workflows directly ○ UML ステートチャート に基づいている ○ C# の dotnet-state-machine/stateless を Go に移植したもの ● スター数: 945 (※ 2024/10/16 時点) ● リリース: v1.7.1 (2024/08/23) qmuntal/stateless

Slide 24

Slide 24 text

● いろんなタイプの状態とトリガーをサポート ○ int, string, boolean, struct, etc… ● 階層化構造 ● Entry/exit イベント ● 条件付き遷移をサポートするガード機構 ● スレッドセーフ ● etc… qmuntal/stateless

Slide 25

Slide 25 text

● ステートマシン設定方法は、たったこれだけ! ○ ステートマシン初期化 ○ Configure 関数と Permit 関数をつかって定義 ○ Fire 関数にトリガーを渡す qmuntal/stateless

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

なんか「良い感じ」に使いやすいかも

Slide 28

Slide 28 text

● ドキュメントが簡潔でよい ○ This page is an almost-complete description of Stateless, and its explicit aim is to remain minimal. ● 直感的に使える ○ looplab/fsm だと既存パラメータに対して合成して使っていた ○ 基本的には Configure() と Permit() を使って定義するだけ ■ どのトリガーを使い、どこに遷移するのかわかりやすい 推しポイント

Slide 29

Slide 29 text

推しポイント ● トリガーに定数が使えるので誤字によるミスが防げる ○ 内部実装的には Trigger は any ○ looplab/fsm は string 指定だったので独自型が使えなかった

Slide 30

Slide 30 text

とはいえ API リクエストごとに ステートマシンを初期化するのなんか冗長だな

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

ステートマシンの初期化を一度だけにするには ● NewStateMachineWithExternalStorage を使う ○ 初期化に適当な状態をいれておく ○ 変更前の状態を適用させステータス変更処理を実行する ○ https://github.com/qmuntal/stateless/issues/72

Slide 33

Slide 33 text

NewStateMachineWithExternalStorage を使う理由 ● NewStateMachine ○ 内部状態 (State) を自分自身で保持 ○ 内部で stateAccessor と stateMutator を持つ ○ 状態を参照・変更するためにローカルメモリでのアクセスを行う ■ あとから初期状態を変更することができない

Slide 34

Slide 34 text

NewStateMachineWithExternalStorage を使う理由

Slide 35

Slide 35 text

NewStateMachineWithExternalStorage を使う理由

Slide 36

Slide 36 text

実際に NewStateMachineWithExternalStorage を使った例

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

外部ストレージを使うことで リクエストごとに初期化しなくて済んだ 🙌

Slide 40

Slide 40 text

まとめ

Slide 41

Slide 41 text

まとめ ● qmuntal/stateless を使ってみて ○ 良かったこと ■ 定数が使えるので誤字によるミスが防げた ■ 簡単に新しい「状態」を増やすこともできる ■ テストも楽になった ■ それから猿人バーゴンも発見することができた ○ 課題感 ■ mermaid からコード自動生成できるといいな

Slide 42

Slide 42 text

ステートマシンを導入するなら qmuntal/stateless はどうでしょうか

Slide 43

Slide 43 text

Thank you

Slide 44

Slide 44 text

● https://thinkit.co.jp/article/10012 ● https://www.slideshare.net/slideshow/statemachinefull/40100048 ● https://github.com/qor/transition ● https://github.com/bykof/stateful ● https://github.com/bykof/stateful?tab=readme-ov-file#draw-graph ● https://github.com/looplab/fsm ● https://github.com/oxplot/fysom ● https://github.com/jakesgordon/javascript-state-machine ● https://github.com/qmuntal/stateless ● https://en.wikipedia.org/wiki/UML_state_machine ● https://github.com/dotnet-state-machine/stateless ● https://github.com/qmuntal/stateless?tab=readme-ov-file#project-goals 引用