CLAUDE LABEN
SLACK — Claude TagがSlackでベータ提供。チャンネルで@Claudeにタスクを委譲し、ツール・データ・コードベースを接続できますSECURITY — Claude Codeにsandbox.credentials設定が追加。認証ファイルや秘密の環境変数の読み取りをブロックできますFIX — リモートMCPツール呼び出しの5分ハングを修正。応答なしで止まらずエラーで中断しますMCP — 組織向けMCPコネクタがOktaプロビジョニングに対応。初回ログインでゼロタッチ接続できますMODEL — Claude Fable 5は100万トークン文脈・常時アダプティブ思考・128K出力を備えますLINEUP — 主力はOpus 4.8・Sonnet 4.6・Haiku 4.5。用途に応じて使い分けられますSLACK — Claude TagがSlackでベータ提供。チャンネルで@Claudeにタスクを委譲し、ツール・データ・コードベースを接続できますSECURITY — Claude Codeにsandbox.credentials設定が追加。認証ファイルや秘密の環境変数の読み取りをブロックできますFIX — リモートMCPツール呼び出しの5分ハングを修正。応答なしで止まらずエラーで中断しますMCP — 組織向けMCPコネクタがOktaプロビジョニングに対応。初回ログインでゼロタッチ接続できますMODEL — Claude Fable 5は100万トークン文脈・常時アダプティブ思考・128K出力を備えますLINEUP — 主力はOpus 4.8・Sonnet 4.6・Haiku 4.5。用途に応じて使い分けられます
記事一覧/API & SDK
API & SDK/2026-06-25上級

前の実行が終わらないうちに次が走り出すとき — リースとフェンシングトークンで定期エージェントの多重起動を抑える

毎日決まった時刻に動く定期エージェントが、前の実行を追い越して二重に走り出す。素朴なロックが破れる瞬間から、リースとフェンシングトークン、上限付きキャッチアップまでを実装込みで整理します。

Claude Agent SDK10スケジュール実行2分散ロック本番運用31設計4

プレミアム記事

「まだ前の処理が走っているのに、もう次が始まっている」。Dolice Labs で4サイトの記事を毎日決まった時刻に生成している仕組みを眺めていて、ある朝そう気づきました。

きっかけは、Claude Code の API 上限が引き上げられて、それまで余裕を持って空けていた実行間隔を少し詰めたことでした。間隔を 45 分に縮めた直後、たまたま生成が長引いた回があり、前の実行がまだ後片付けをしている最中に、次の cron が新しいプロセスを立ち上げていました。記事が二重に push されかけて、git の履歴を見て手が止まりました。

定期実行は「時刻が来たら走る」だけの素朴な仕組みに見えて、実は前の自分とすれ違う瞬間に弱点を抱えています。今日は、その多重起動をどう抑えるかを、素朴なロックが破れる瞬間からフェンシングトークンまで、私が実際に置いている実装とともに辿っていきます。

なぜ「前を追い越して」次が走り出すのか

cron や Cowork のスケジュールは「この時刻に開始する」ことだけを約束します。「前の実行が終わってから開始する」とは、どこにも書かれていません。

ふだんは生成が間隔より十分速いので、すれ違いは起きません。ところが本番では、API の一時的な遅延、リトライ、巨大な記事の生成、ネットワークの揺らぎ。どれか一つが噛み合うと、一回の実行が間隔を食い破ります。

すると次の起動はためらいなく走ります。両者は同じリポジトリを clone し、同じ slug を選びかけ、同じファイルに書き込もうとします。片方が git push に成功し、もう片方が rebase で衝突する。運が悪いと、わずかに違う本文の記事が二本生まれます。

この問題の核心は、二つの実行が「自分のほかに誰かいる」ことを知らない点にあります。だから、まず互いの存在を知らせる仕組みが要ります。

まず素朴なロックを置く(そして、それが破れる瞬間)

最初に思いつくのは、開始時にフラグを立てて、終了時に下ろす方法です。

// 素朴版 — これは本番では破れます
async function runOnce(store, jobId, body) {
  if (await store.read(jobId)) {
    return { ran: false, reason: "locked" };
  }
  await store.write(jobId, { running: true });
  try {
    await body();
  } finally {
    await store.write(jobId, null); // 解放
  }
}

短時間なら、これで多くのすれ違いは防げます。私も最初はこの形でした。

けれども、二つの穴が残ります。

一つ目は、解放されないロックです。実行が途中でクラッシュしたり、VM ごと落ちたりすると、finally に辿り着けません。フラグは立ったまま残り、翌日からすべての実行が「locked」で弾かれます。無人で回す仕組みでは、これに気づくのが数日後になります。私自身、AdMob のレポートを毎朝取得するジョブで、これに似た固まり方を経験しました。

二つ目は、もっと厄介です。ロックを持っているはずの実行が、実はとっくに死んでいるのに、OS から見ると「まだ生きている」状態。あるいは、長く一時停止していたプロセスが、誰かに見捨てられた後でふと目覚めて、最後の書き込みだけを実行してしまう状態。フラグの有無だけでは、この「ゾンビ」を止められません。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
実行間隔より生成が長引いたときに多重起動を止める、TTL付きリースロックの最小実装(TypeScript・任意ストア対応)
期限切れの実行が遅れて書き込む事故を、書き込み先でフェンシングトークンを検証して止める設計と落とし穴
障害復帰後の取りこぼしを上限1スロットで畳む、キャッチアップ方針と実測の重複スキップ率(全実行の約2%)
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

API & SDK2026-06-02
自律エージェントの破壊的操作に事前条件・事後条件の契約ゲートを付ける
自律エージェントが本番に書き込む前後を、決定論的な事前条件・事後条件で挟む契約ゲートの設計です。プロンプト改善では防げない破壊的操作を、コードで止める実装を紹介します。
API & SDK2026-05-31
再現できないエージェント障害をなくす設計 — 決定論的リプレイとイベントソーシング
深夜に落ちた自律エージェントは、そのままでは再現できません。モデル出力やツール入出力など非決定の境界をイベントとして記録し、決定論的にリプレイする設計を、実装コードと運用知見つきで解説します。
API & SDK2026-05-20
Claude Agent SDK で複数 MCP サーバを束ねるときのツール名衝突 — 名前空間と動的調停の設計
GitHub MCP と Linear MCP の create_issue が同居したとき、Sonnet 4.6 はどちらを呼ぶか分かりません。複数 MCP を束ねる Claude Agent SDK アプリで踏むツール名衝突の構造と、TypeScript で書ける Reconciler の実装、本番で踏んだ失敗パターンまでをまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →