fix: D1のbind上限で自動要約が無限に課金されるのを止める - #77
Merged
Merged
Conversation
D1は1文あたりのbindパラメータを100個までしか受け付けず、この上限は d1.batch()の中でも文ごとに個別適用される。PUT /channel/summary の確定 UPDATEは channel_id 1個 + message_id 最大200個をバインドしていたため、 未要約が100件たまったチャンネルでは必ず101個以上になり、prepareの時点で 拒否されていた。 batchはトランザクションなので、確定の失敗がカーソル前進ごとロールバック する。一方でLLM呼び出しと記憶の作成はその前に完了しているため、進捗が 一切進まないまま10分ごとに同じ200件を要約し直していた。2026-09-02から 6日半で833回、重複記憶833件。 候補条件が pending_count >= 100、取得上限が MAX_MESSAGES_PER_RUN = 200 なので、件数経路で候補になった瞬間にバインドは必ず101..=201になる。 偶発ではなく確定で踏む。 - shared: D1_MAX_BOUND_PARAMS と confirm_pending_chunks を追加し、確定 UPDATEを99件ずつに分割する。分割してもbatchはトランザクションなので 原子性は保たれ、行トリガの発火回数も行数で決まるため結果は変わらない。 workersはワークスペースからexcludeされていて workers/src に書いた テストはCIで走らないので、検査可能な形にするためsharedに置く。 - workers: 確定UPDATEを分割版に差し替える。Vectorizeの deleteByIds も 100件上限があるので同様に分割する(記載は無いがcode 40007で落ちる)。 search_memory の clamp を定数に結び直す。 - app: tracing-subscriberを初期化する。依存はtracingだけでsubscriberを 張っていなかったため、この事故のerror!は833回とも捨てられていた。 - app: 連続5回失敗したチャンネルを自動要約から外す。確定できない状態で 回り続けると要約費用だけが積み上がるため、支払いを有界にする。 - app: 見送ったチャンネルがtick枠を消費していたのを直す。詰まった1つが 他を飢えさせていた。 - ci: workersをPR段階でclippyにかける。exclude配下なので、これまで deployジョブまで一度もコンパイルされていなかった。 - workers/tests/d1_bind_probe.sh: 「定数がプラットフォームの実際の上限を 超えていないか」を実D1で確かめる。ユニットテストが守るのは 「コードが定数を超えない」ことだけで、両方揃わないと不変条件が閉じない。 - summary_state.sh: 素のsqlite3ではこの上限を検査できないことを明記する。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
案内として要らない説明・経緯・実装の性質を落とし、生きた制約だけを残す。 - workers/tests/d1_bind_probe.sh を削除。wrangler の認証が要るので CI から 呼べず、誰も走らせない。実 D1 での確認手順は docs/003_observability.md に 文章で残す。 - shared: max_variable_bindings を削除し、呼び出し側で D1_MAX_BOUND_PARAMS を 直接使う。ConfirmChunk の未使用 derive も落とす。 - shared から workers へ: VECTORIZE_MAX_DELETE_IDS を使う側に移す。shared は app と worker が共有する DTO の置き場で、app はこの定数を使わない。 - コメントを書き直す。関数 doc は「<入力> から <出力> を返す。」の1行を基本に し、事故の再話・正しさの証明・他モジュールとの分担は落とす。 プラットフォームの上限そのもののような、今も効いている制約は残す。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
出力量の制約は経緯ではなく、subscriberを入れた直後にまさに効く。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
Author
|
連続5回失敗したチャンネルを自動要約から外すようにするやつって失敗を不可視化するだけなんとちゃうの |
連続失敗で自動要約から外す機構は支払いを有界にするが、諦めたことは error! 1行しか残らない。docker logs はコンテナごと消え、以後は tick ごとに黙って飛ばすだけなので、失敗が不可視化される。 外した瞬間に1回だけデバッグチャンネルへ通知し、チャンネル・連続失敗 回数・最後のエラー・再起動するまで止まったままであることを伝える。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Remove commented-out notes regarding cargo test behavior and worker checks.
Removed commented lines about tracing subscriber configuration.
Removed comments in Cargo.toml for clarity.
Owner
Author
|
あー眠くてあんまりコード監査してないけどマージしちゃう もう眠いから…… |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
起きていたこと
Cloudflare D1 は1文あたりの bind パラメータを100個までしか受け付けない。
しかし、
PUT /channel/summaryで実行される UPDATE はchannel_id1個 +message_id最大200個をバインドしていて、要約の記録に毎回失敗していた。一方で、UPDATE 前のサマリー生成は10分おきに稼動していたので、LLM APIに毎回同じ200メッセージが投げられていた。
修正したこと
D1_MAX_BOUND_PARAMSとconfirm_pending_chunksを追加。UPDATE を99件ずつに分割することにした。deleteByIdsにも100件上限があるので同様に分割した。tracing-subscriberを初期化して、連続5回失敗したチャンネルを自動要約から外すようにした。workersを PR 段階で clippy にかける。memory.timestampが時系列順に並ばない件を追記。🤖 Generated with Claude Code