Repository navigation
feat: keep workflow_run intermediates stored but out of the foreground count #256
Description
書き直し済み。 初版は「ingest 時点で
requested/in_progressを捨てる」だった。イベント駆動の起動条件としてそれらが load-bearing であるという指摘を受け、保存は維持して前景表示のみを絞る形に変更。撤回の理由は下記## 初版の誤り参照。
purpose
workflow_run の requested / in_progress を 保存したまま、前景の pending カウントと intake 報告から外す。foreground の見通しを回復しつつ、イベント駆動 consumer の起動トリガを失わない。
premise
実測(pending 100 件サンプル、list_pending_events limit=100、received_at 降順):
type 別: action 別:
workflow_run 86 in_progress 37
issue_comment 8 completed 25
pull_request_review 6 requested 24
created 7
submitted 6
edited 1
workflow_run が 86 / 100。GitHub は 1 run につき requested / in_progress / completed の 3 件を送るため、run 数の 3 倍が積む。
1 run = 3 件の構造は直接観測済み: run 35339438755 が 3 件を順に配送。比率のほうは上限 100 の窓による標本なので、母集団比率としては扱わない(211 件中の古い側 111 件は list_pending_events から到達不能)。
前景の問題: 毎ターン注入される pending カウントが 3 倍に膨らみ、外部イベント(他アカウントの comment / review)が数字の中に埋もれる。
初版の誤り
初版は ingest でこれらを捨てる設計だった。根拠として「中間状態を読んで分岐する経路は consumer 側に存在しない」と書いたが、これは現時点の consumer のみを見た判断であり、母集団を現在の標本で代表させる誤り。
イベント駆動動作では requested は run 開始のトリガとして load-bearing である。completed をポーリングで探す設計と、requested を受けて待機に入る設計は別物で、後者は中間 action を必要とする。Li+ 側は substrate 層の event-driven を保留状態と位置づけており(rules/evolution/evolution.md Evolution Layer)、まだ存在しない consumer がこの面に来る。
可逆性が決め手: ingest で捨てるのは不可逆(その consumer は二度と受け取れない)、保存して表示を絞るのは可逆(述語を外せば戻る)。
2 つの action は別々の根拠で必要
まとめて「イベント駆動で要る」と書くと、片方だけを削る提案が後から通る。根拠を分けて記録する。
requested = 起動トリガ。run が立ったこと自体の通知であり、待機状態へ入る合図になる。これが無いと、イベント駆動 consumer は run の存在を completed まで知らない。
in_progress = 状態遷移の確定。queued から running への遷移を表す。これにより「キューで滞留している」と「実行中である」が区別できる。
in_progress の配送回数(実測): 1 run につき 1 回とは限らない。
同一標本を run ID で紐付けて数え直した結果:
distinct run 25 本
requested 24
in_progress 37 ← run 数を上回る
completed 25
うち in_progress を 2 件上げた run 12 本
2 件上げた run の例: 35334833326 35334525192 35329222535 35328921258 35328742856
定期 heartbeat ではない(間隔が一定でなく、走行中ずっと流れ続けてもいない)。かつ遷移時 1 回でもない。観測上は 1 run あたり平均 1.5 件。複数件になる条件は未特定(ジョブ構成との関係は未検証)。
したがって件数の見積もりは run 数 × 3 ではなく、requested 1 + in_progress n + completed 1 が実測に合う。削減を論じる際、in_progress は「1 種類ぶん」ではなく最多カテゴリとして効く。
配送回数がどうであれ、区別できる状態は以下であり、これが load-bearing な部分:
requestedのみ受信、in_progress未着 → キューで滞留(runner 待ち / 同時実行上限)requested+in_progress受信、completed未着 → 実行中に停止(ハング / タイムアウト待ち)
polling ならいつでも再問い合わせで現在状態が取れるが、イベント駆動には問い合わせが無い。この 2 状態の区別は受信済みイベントの組み合わせからしか得られない。
constraints
- ingest は変更しない。全 action を従来どおり保存する。
mark_processedの対象からも外さない。明示的に id を渡せば従来どおり処理できる。- 絞るのは前景表示のみ = pending カウントの集計と、intake が報告対象とするかの判定。
completedの扱いは不変。成否判定ロジック(SUCCESS_CONCLUSIONS参照箇所)に入力の変化は無い。- 保存が増え続ける点は retention sweep が担当(
worker/src/store.tsの DO-alarm sweep、feat(worker): time-based retention sweep for unprocessed events via DO alarm #237)。本 issue で窓の値には触れない。 check_runは対象外。同様の中間 action を持つが、今回の標本に出現しておらず根拠が無い。含めるなら別途計測する。
target files
未確定。前景カウントをどこが生成しているかの特定が先。
候補:
get_pending_statusの集計経路 — 毎ターン注入される件数の出どころlist_pending_events— 既定の返却対象から外すか、include_intermediate相当のオプトインにするか
設計上の選択が 1 つ未決: 既定で隠して明示指定で見えるようにするか、常に返して呼び出し側が絞るか。前者は呼び出し側を変えずに効くが、既定の意味を変える。
補足
Liplus-Project/liplus-language#1996 の調査中に副次的に発見。#1996 は Li+ 側の rule 記述修正で、本 issue とは独立。
Activity
[-]feat(worker): drop workflow_run requested/in_progress at ingest, keep completed only[/-][+]feat: keep workflow_run intermediates stored but out of the foreground count[/+]