永続的な遅延:時間を分散状態として管理する

SchemaBridge Team · 2026-01-10 · Time, Scheduling, Orchestration

メモリリークを起こさずに30日間の待機期間を扱う。なぜ`sleep()`は分散システムにおけるアンチパターンなのか。

sleep()という嘘:なぜ時間は最も難しい分散プリミティブなのか

あらゆるプログラミング言語には、待機のためのコマンドが存在します。Pythonならtime.sleep()、Node.jsならsetTimeout()、JavaならThread.sleep()です。これらのコマンドはシンプルで直感的ですが、数秒を超える複雑さになると、本番の分散システムにおいてはまったく役に立ちません

この素朴なsleep()が嘘である理由は、環境が安定していることを前提としているからです。コードを実行しているマシンが生き続けること、ロードバランサーによってプロセスがキルされないこと、そしてOSによってメモリが回収されないことを前提としているのです。現代のクラウド環境では、これらの前提はすべて偽です。標準的なKubernetesのPodでsleep(24 60 60)(1日)を実行すれば、その日が終わる前にPodがローテーションされる、スケールダウンされる、あるいは再デプロイされる確率は99%です。

プロセスが死ねば、あなたの「sleep」も一緒に死にます。ビジネスロジックは虚無の中に消え去ります。こうして「忘れっぽいソフトウェア」――顧客のトライアル期間を見失い、サブスクリプションの更新を逃し、重要なフォローアップメールの送信に失敗するシステム――が生まれるのです。

時間の階層:秒単位から月単位まで

時間を正しく管理するには、まずそれを分類する必要があります。すべての遅延が同じように扱えるわけではありません。

1. 一過性の遅延(ミリ秒〜秒単位):これは通常、ネットワークのバックオフや、高速なデータベースロックの待ち時間です。50msという短い時間枠でのクラッシュリスクは低いため、sleep()が許容される場合もあります。

2. 短時間の遅延(分単位):ここでsleep()は破綻し始めます。何もしないままワーカースレッドやコンテナのリソースを数分間占有することになります。これは金銭的な無駄であり、コネクションプールに対するリスクでもあります。

3. 永続的な遅延(時間〜月単位):これはビジネスライフサイクルの領域です。14日間の無料トライアル、30日間の支払い猶予、あるいは6か月ごとのメンテナンススケジュール。これらはコードの中に存在させることはできません。インフラの中に存在させる必要があります。

「眠る」ワークフローのアーキテクチャ

SchemaBridgeでは、時間を永続的な状態(Durable State)として扱います。ワークフローが「Delay頂点」に到達すると、スレッドをブロックすることはありません。自身をディスクへとシリアライズし、メモリ上には存在しなくなるのです。

DBポーリングモデル(低精度・高耐久性)

「起床時刻」をデータベースのテーブルに保存します。バックグラウンドワーカー(「ポーラー」)が数秒ごとにテーブルへ問い合わせます:SELECT * FROM timers WHERE wake_up < NOW()。DBレコードは何年でも生き延びられるため、これは驚くほど耐久性があります。

SchemaBridgeのアプローチ

SchemaBridgeはDynamoDBを裏付けとした永続的スケジューリングエンジンを使用します。私たちは「起床する」という意図をScheduledTaskRepositoryに明示的に永続化します。これにより、データベースレコード並みの、千年単位の耐久性が得られます。

シグナルと割り込み:未来を変える

永続的な遅延も、キャンセルや変更ができなければ意味がありません。ユーザーが「支払いを3日間待つ」頂点にいて、2時間後に支払いを済ませた場合、ワークフローを即座に起こして先に進める必要があります。

SchemaBridgeは外部シグナルをサポートしています。シグナルとは、実行中のワークフローに対して送信されるイベントです。

これらのスケジュールされたタスクをキャンセルまたは割り込むための明示的なAPIも提供しています(例:nukeコマンドでcronジョブを停止する、あるいはWebhookシグナルで特定の遅延に割り込むなど)。遅延とシグナルの両方がエンジンによって処理されるため、システムは競合状態(レースコンディション)の影響を受けません。

グローバルメッシュにおけるクロックドリフトと精度

複数のAWSリージョンにまたがる分散システムでは、クロックが完全に同期することはありません。これがクロックドリフトという現象です。リージョンAのクロックがリージョンBよりも50ms進んでいる場合、「1秒待機」の挙動はタスクがどこで処理されるかによって変わってしまう可能性があります。

SchemaBridgeは、中央集約されたメタデータレイヤーから導出される論理クロックシグネチャを用いてこれを解決します。個々のワーカーは実行にローカルクロックを使用しますが、「時間の意図」はグローバルに同期され、不変の履歴に記録されます。ワーカーのクロックが多少ずれていても構いません。重要なのは、実行の継続時間があなたのビジネス上の意図と一致していることです。

ケーススタディ:失敗率0%で30日間のドリップキャンペーンを自動化

私たちは、「ウェルカムジャーニー」のロジックに苦戦していたマーケティングオートメーションプラットフォームと協業しました。

課題

ジャーニーは次のような構成でした。

彼らはCronジョブとPostgresテーブルによる独自構築のソリューションを使用していました。毎週、データベースのメンテナンスウィンドウやデプロイのたびに、およそ5%のユーザーが待機状態で「スタック」してしまい、次のメールを二度と受け取れなくなっていました。毎月、コンバージョンによる潜在収益を数千ドル単位で失っていたのです。

SchemaBridgeによる方法

彼らはユーザージャーニーをSchemaBridgeのワークフローへ移行しました。

1. ビジュアルな遅延:文字通り「Delay」頂点をグラフ上にドラッグし、3d7dに設定するだけでした。

2. 永続的な再開:デプロイ中、ワークフローは単にデータベース上で一時停止するだけでした。エンジンがオンラインに復帰すると、ダウンタイム中に期限切れとなったタイマーを検知し、正しい順序で即座に再開しました。

3. シグナル連携:彼らは私たちのWebhookゲートウェイを使って「クリック」シグナルを送信しました。ユーザーがメールをクリックすると、ワークフローは即座に起き、残りの遅延をスキップして「成功」パスへと遷移しました。

結果

比較:既存のスケジューリング戦略

| 項目 | setTimeout() | Cronジョブ / Quartz | SchemaBridge永続的遅延 |

| :--- | :--- | :--- | :--- |

| 永続性 | なし(揮発性) | 手動(DBベース) | ネイティブ(永続的な履歴) |

| スケーラビリティ | 低い(RAM依存) | 中程度(DBボトルネック) | 高い(シャード化されたDDB) |

| キャンセル | 複雑(手動ハンドル) | 手動でのDBクリーンアップ | ビジュアルなシグナル/割り込み |

| 可視性 | なし | SQLクエリ | ビジュアルな進捗ダッシュボード |

| 分解能 | ミリ秒単位 | 秒/分単位 | マネージドポーリング |

長時間実行されるビジネスロジックのためのエキスパートチェックリスト

5分を超えて待機するシステムを設計する場合は、次のヒューリスティクスに従ってください。

1. スレッドを止める:待機中にワーカーをブロックしてはいけません。ワーカーはステートレスであり、いつでもキルされる準備ができているべきです。

2. クロックを外部化する:時間の経過を管理するにはローカルマシンのシステム時刻ではなく、中央のエンジンを使ってください。

3. 割り込みを前提に設計する:ユーザーが、待っているアクションを遅延の期限が切れる前に行う可能性を常に想定してください。シグナルを使って待機を「割り込み可能」にしましょう。

4. 待機室を監査する:ダッシュボードを使って、現在何千(あるいは何百万)ものワークフローが「休眠」状態にあるかを確認してください。これはビジネスの健全性を示す重要な指標です。

5. 論理オフセットを活用する:起床時刻に固定タイムスタンプ(例:「1月15日」)を使わないでください。論理オフセット(例:+3d)を使うことで、ワークフローの最初のステップが遅延した場合でも、相対的な間隔が一貫して保たれます。

結論:時間はインフラの問題である

忘れるソフトウェアは、失敗するソフトウェアです。時間を第一級の永続的な分散状態として扱うことで、私たちはリアルタイムのイベントと、レイテンシの高い人間の行動との間にあるギャップを埋めます。SchemaBridgeを使えば、ミリ秒単位のロジックを構築するのと同じ確信を持って、数か月にまたがるジャーニーを構築できます。

「体験の経済(Experience Economy)」の時代において、インタラクションのタイミングを完璧に管理する能力は、あなたにとって最大の競争優位です。私たちが提供するのは時計であり、あなたが提供するのはジャーニーです。

第8回では「オブザーバビリティ・ギャップ」を取り上げ、ログの中で正気を失うことなく、こうした複雑で数日にまたがる分散チェーンをビジュアルにデバッグする方法を見ていきます。

詳しく見る