コンテンツにスキップ

archives

台帳。成功した取り込みが 1 本につき 1 行です。「どの WACZ がどこに在るか」の 記録で、署名付き URL を発行するときの参照先になります。

.addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`))
.addColumn("task_id", "uuid", (col) => col.notNull())
.addColumn("correlation_id", "text")
.addColumn("bucket", "text", (col) => col.notNull())
.addColumn("object_key", "text", (col) => col.notNull())
.addColumn("source_url", "text", (col) => col.notNull())
.addColumn("labels", sql`text[]`, (col) => col.notNull().defaultTo(sql`'{}'::text[]`))
// CaptureResultReport.completeness.complete。`false` は、そのアーカイブに
// 本文が 1 つ以上欠けているという意味 —— 304 としてしか見なかった URL か、
// 容量の上限を超えて BrowserHive が落としたもの (後者は v1.11.0 で加わった。
// それ以前、上限に当たった取り込みは `true` と報告していた)。アーカイブを
// wacz-validator に渡す前に知っておく価値がある。この field より前の取り込みや、
// 記録しなかった取り込みでは NULL。
.addColumn("wacz_complete", "boolean")
// ledger が受け取った時刻ではなく、BrowserHive 自身が付けた取り込みの時刻。
// reconciler は何時間も後に行を登録しうるので、履歴を並べ替えてはならない。
.addColumn("captured_at", "timestamptz", (col) => col.notNull())
.addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))

所有者の列が無いことに意味がある

Section titled “所有者の列が無いことに意味がある”

owner_id も org_id もありません。誰が読んでよいかは「関係」であり、 OpenFGA が持ちます。

同じ問いへの答えを 2 か所に置けば、いずれ食い違います。ここに org_id を置くと、 「テーブルではこの組織だが、OpenFGA では別の組織に紐づいている」という状態が 作れてしまいます。

代わりに、登録と同時に fga_outbox へ tuple を 積み、OpenFGA 側で関係として表します。

if (report.status !== CaptureStatus.CAPTURE_STATUS_SUCCESS ||
report.artifacts?.wacz === undefined) {
log.warn(…, "capture produced no archive; not adding to the ledger");
return { reason: "no-archive" };
}

失敗した取り込みは何もアップロードしていません。 それを記録すると、署名の エンドポイントが存在しないオブジェクトの URL を配ることになります —— 404 に対して認可が完璧に働いている状態で、最も気づきにくい壊れ方です。

だからcapture_submissionsの件数と この表の行数は一致しません。差が出るのが正常です。

台帳を埋める道は 2 本あります。

  • クロール — flow が段を報告した時点で、取り込めたぶんを登録する(速い)
  • reconciler — capture_submissions に書き留めた manifest の鍵を読み、台帳に無いものを登録する(穴を埋める)

両方が同じ取り込みに辿り着けますし、どちらも再実行されえます。

.onConflict((oc) => oc.columns(["bucket", "objectKey"]).doNothing())

(bucket, object_key) が UNIQUE なので、それは重複ではなく無操作になります。 そして挿入されなかった場合は tuple も積みません —— 既に台帳に在るなら、tuple は 最初のときに積まれているからです。

列 要点
id gen_random_uuid()。OpenFGA の archive:<id> になる
task_id BrowserHive のタスク id
correlation_id capture-ledger のログ行と成果物のファイル名を結ぶ糸(送信ごとの 16 進 8 桁)
bucket / object_key server 自身の報告から取る。 ファイル名を組み直したものではない
wacz_complete false は本文が 1 つ以上欠けているという意味。詳細は下記
captured_at 取り込みの時刻。一覧はこれの降順

CaptureResultReport.completeness.complete をそのまま入れています。false は そのアーカイブに本文が 1 つ以上欠けているという意味です。

  • 304 としてしか見なかった URL
  • 容量の上限を超えて BrowserHive が落としたもの

後者は BrowserHive v1.11.0 で加わりました。それ以前、上限に当たった取り込みは true と報告していました。 この field より前の取り込みや、記録しなかった 取り込みでは NULL です。

アーカイブを wacz-validator に渡す前に知っておく価値があります。

archives_pkey PRIMARY KEY (id)
archives_bucket_object_key_key UNIQUE (bucket, object_key) -- 二重登録の防止
archives_captured_at_idx (captured_at DESC) -- 一覧は新しい順
archives_task_id_idx (task_id) -- 報告から引く