Skip to content

[Job] media・crop処理状態をdomain side-tableへ移行する #620

Description

@hmjn023

Parent: #612

Depends on: #615, #619

背景

media に単一status enumを追加するだけでは、tagging、full-image CCIP、crop CCIPなど複数処理の同時進行、元画像・model更新、失敗・再試行を表現できない。generic jobの履歴から間接的に推測せず、対象と処理種別ごとの現在状態をdomain modelとして管理する。

設計方針

  • FKを維持できるmedia/region processing side-tableを用意する
  • (target_id, task_kind) を一意にする
  • statusrequested_revisioncompleted_revisionclaim_tokenclaimed_atheartbeat_atattempt_countavailable_atlast_error を保持する
  • revisionへ元画像更新、model、embedding version、抽出条件を含める
  • workerはatomic claimし、古いclaimが新revisionをreadyへ戻せないようCAS/token検証する

スコープ

  • domain/Zod schema、Drizzle schema、repositoryと明示的mapper
  • tagging、full CCIP、crop CCIPのdual-write/backfill
  • status API/UIをside-table参照へ切り替える
  • retry/backoff、stale recovery、concurrent worker、lost-updateのテスト
  • batch進捗を処理状態の集計から算出できるようにする

非スコープ

  • import、download、source syncの管理
  • generic jobs の即時削除
  • embedding本体のLanceDB移行

受け入れ条件

  • 同一media/region上の複数taskが互いを上書きしない
  • revision変更時に確実に再処理対象になる
  • 旧workerが新しい要求を完了扱いにできない
  • 失敗理由・試行回数・次回実行時刻を確認できる
  • 再起動後もUIがDBから正しい現在状態を復元できる
  • tagging/full CCIP/crop CCIPがgeneric jobなしで処理できる

主な参照

  • packages/db/src/schema.ts:145
  • apps/server/src/infrastructure/api/routers/ai-router.ts:416
  • apps/server/src/infrastructure/jobs/job-worker.ts:56
  • packages/application/src/services/ccip-vector-service.ts:153

評価反映(2026-07-18)

既存設計を以下のとおり具体化する。

FKを維持するprocessing state

polymorphicなtarget_id単独tableは、mediaとregionの両方へ外部キーを設定できないため採用しない。少なくとも次のように対象ごとのtableを分離する。

  • media_processing_states
    • media_idmedia.idへFK
    • (media_id, task_kind)を一意にする
  • region_processing_states
    • region_idmedia_regions.idへFK
    • (region_id, task_kind)を一意にする

削除時のcascade、task kindごとの許可対象、status/claim列の整合CHECKをDBで定義する。repositoryではDB rowからdomain modelへの明示的mapperを設け、polymorphic castで型を合わせない。

revisionとfencingの契約

  • requested_revisionは単なる更新日時ではなく、処理結果を決める入力から決定的に生成する。
    • media file revisionまたはcontent digest
    • task kind
    • model名・model revision
    • embedding/schema version
    • 抽出設定
    • region処理ではbboxおよびregion revision
  • 同じ入力から同じrevisionを生成できるcanonical serialization規則を定義する。
  • 新要求はrequested_revisionをatomicに更新し、既存workerが処理中でも新revisionを失わない。
  • claimはrequested_revision + claim_tokenを固定して取得する。
  • 業務出力とcompleted_revision更新は、可能な限り同一transaction内でrequested_revision + claim_tokenを検証して行う。
  • 旧workerが完了した時点でrequested revisionが変化していた場合、その出力で新要求をreadyへしない。
  • retryはclaimしたrevisionに対して行い、新revisionが要求された場合は旧retryが新要求を上書きしない。

processMediaの処理移行

generic processMediaは現在、metadata抽出とthumbnail生成を実行した後、auto taggingとfull CCIPを投入している。このため、tagging/CCIPだけをside-tableへ移しても#621のjobs削除条件は満たせない。

初期task kindへ少なくとも次を含める。

  • metadata extraction
  • thumbnail generation
  • auto tagging
  • full-image CCIP

各producerを監査し、upload、transfer/copy/move、file watcher、maintenance、restore/import、download後処理から同じrevision規則で要求する。thumbnailのようなfilesystem出力はrevision別の一時出力とatomic replaceを使い、旧claimが新しいthumbnailを上書きしないようにする。

crop CCIPとの依存関係

crop CCIPは#618で延期されているため、既存の「tagging/full CCIP/crop CCIPがgeneric jobなしで処理できる」という受け入れ条件は次の2段階へ読み替える。

  1. 本Issueの初期完了条件
    • metadata、thumbnail、tagging、full CCIPがgeneric jobなしで動作する
    • media向けstate/revision/claim基盤が完成している
  2. #617および#618完了後の拡張条件
    • region_processing_statesを有効化する
    • crop CCIPが同じclaim/revision契約で動作する

region stateの実装はmedia_regionsを提供する#617へ依存し、実験的crop CCIPの#618は本Issueの共通state基盤へ依存させる。#618を本Issueの初期完了のblockerにはしない。

batch進捗との境界

processing stateの集計だけでは、batch開始時点の対象集合、取消後の残件、再開範囲、item別履歴を再現できない。固定された対象集合、正確な進捗、取消・再開、結果履歴を要件とするbatchでは、#621のbatch_itemsを必須とする。

  • processing state: 対象×taskの現在状態
  • batch run/item: そのbatchが要求した対象集合と実行結果

両者を同じtableで兼用しない。

追加の受け入れ条件

  • media stateとregion stateの双方に実FKがあり、孤立targetを作成できない
  • task kindごとのunique制約と、claim/status列の整合CHECKがある
  • revisionのcanonical生成規則とtask別入力項目が文書化されている
  • 新revision要求と旧worker完了を競合させても、新要求がready/完了扱いにならない
  • 業務出力に対するclaim/revision fencingを実DB concurrency testで確認している
  • metadata、thumbnail、tagging、full CCIPの全producerがside-tableへ移行している
  • 再起動後、イベント履歴に依存せずDBから現在状態を復元できる
  • exact batch progressが必要なflowはbatch_itemsを使用し、state集計だけで代用していない
  • crop CCIPを除外した初期完了条件と、[Crop] 画像領域を永続化し派生cropを管理する #617/#618後の拡張条件を別々にテストしている

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions