← AWSサービスの内部原理 コース
91. Parallelは分岐して合流する — 全ブランチの完了を待つAND合流と道連れの失敗
Parallel状態がひとつの入力を複数のブランチに配り、全ブランチの完了を待ってから合流し、そのうち1つが失敗したときに何が起きるのかを、fork/joinの図で追っていきます。
① Branchesは「ミニ・ステートマシンの配列」
Parallel状態"Type": "Parallel"
意味はトップレベルと全く同じ
Branch AStartAt + States
Branch BStartAt + States
各要素が独立したミニ・ステートマシン再帰的な入れ子定義が定義を内包する
- Branchesは必須(Required)で「並列に実行するステートマシンを指定するオブジェクトの配列」
- 各オブジェクトはStatesとStartAtを必ず持ち、その意味は「ステートマシンのトップレベルにおけるものと全く同じ」
Parallelの各ブランチは、トップレベルと同じ「StartAtから始まりStatesを辿る」ミニ・ステートマシン。定義が自分自身を含む再帰的な構造だと気づくと、複雑な並列フローも「同じ部品の入れ子」として読めるようになる。
② forkして、全員を待ってjoinする — AND合流
入力
全ブランチが終端に達するまで待つ
Branch A実行中
Branch B先に終了→待つ
Branch C実行中
最も遅いブランチが律速全員そろってから
join=AND合流バリア同期
Next へ
- 公式: 各ブランチをStartAtの状態から「できる限り並行に(as concurrently as possible)」実行する
- 公式: 「すべてのブランチが終端(terminal state)に達するまで待ってから」Nextフィールドを処理する
Parallelはfork(分岐)とjoin(合流)のペア。joinは全ブランチの完了を要求するAND合流=バリア同期であり、速さは最も遅いブランチで決まる。
③ ブランチは自己完結が必須 — 構造化された並行性
StartAt唯一の入口
境界を越えるNextは禁止
Branch AS1 →(Next)→ S2
Branch BS3 →(Next)→ S4
✗ S2→S3(跨ぎ)も ✗ 外→S1(進入)も不可join点唯一の出口
- 公式: 「各ブランチは自己完結(self-contained)でなければならない」— ブランチ外を指すNextも、外の状態からブランチ内への遷移も不可
- goto的な境界越えを禁じることで「forkした制御は必ず同じjoin点に戻る」不変条件が保たれる(structured concurrency)
ブランチ境界は越えられない。入口はStartAtだけ、出口はjoin点だけ。この閉じ込めがParallelの合流を破綻させない前提になっている。
④ 入力はコピーで配られ、出力は「結果を並べた配列」
入力 [3, 2]
ブランチ順に集約(fan-in)
Add3 + 2 = 5
Subtract3 - 2 = 1
どちらも同じ [3, 2] を受け取る出力 [5, 1]ブランチごと1要素の配列
- 配られるコピーはInputPathフィールドによる修正を受け得る
- 公式: 「すべての要素が同じ型である必要はない(There is no requirement that all elements be of the same type)」
- 例は公式のFunWithMathステートマシンそのまま
入力はコピーして配り(fan-out)、出力はブランチ順の配列に集約する(fan-in)。[3,2]→[5,1]はこの配り方と集め方をそのまま表した最小の例。
⑤ 道連れの失敗(fail-fast)— 1つ落ちれば全員止まる
Branch A実行中
Branch B ✗未処理エラー or Fail状態
Branch C実行中
Parallel自身で捕捉されなければ
Parallel全体が失敗全ブランチ停止=道連れ
実行がエラー停止
- 公式: いずれかのブランチが未処理エラーまたはFail状態への遷移で失敗すると、Parallel状態全体が失敗とみなされ全ブランチが停止される
- ④の帰結: 全員の結果で配列を作る以上、1つ欠けが確定した瞬間に残りを続ける意味がなくなる
AND合流の裏返しがfail-fast。1つのブランチの失敗はParallel全体の失敗であり、他の全ブランチも(論理的に)停止される。
⑥ 「論理的に止まる」と「物理的に止まる」は別 — 遠くのプロセスは殺せない
Step Functions側ブランチを論理的に停止
ワーカー側Lambdaもアクティビティワーカーも動き続ける
動作中のLambdaは止められないエラーを合図に
エラーが返る「もう失敗している」の合図
ワーカーが自己終了自分で処理を止める
- 公式Note: Parallel状態が失敗しても呼び出し済みのLambda関数は動き続け、タスクトークン処理中のアクティビティワーカーは停止されない。「Running Lambda functions cannot be stopped」
- 状態失敗後の SendTaskHeartbeat / SendTaskSuccess / SendTaskFailure はエラーを返す
- Lambdaのフォールバックを用意する場合はWait状態を挟み、Lambda終了後にクリーンアップが走るようにする
- ParallelにはRetry/Catchも書けるので、道連れの前にブランチの失敗を受け止めてフォールバックへ逃がせる
Step Functionsが止められるのは「論理的な制御」だけ。実行中のLambdaや処理中のワーカーという「物理的な計算」は止められず、ハートビートのエラーを合図に自己終了させる——遠くのプロセスは殺せないという分散システムの現実が、fail-fastの理想の裏に控えている。