diff --git a/apps/server/src/orchestration-v2/ProjectionStore.test.ts b/apps/server/src/orchestration-v2/ProjectionStore.test.ts index acf50f00476e..203c497f0ce4 100644 --- a/apps/server/src/orchestration-v2/ProjectionStore.test.ts +++ b/apps/server/src/orchestration-v2/ProjectionStore.test.ts @@ -4341,7 +4341,7 @@ it.layer(layerTest)("ProjectionStoreV2", (it) => { }), ); - it.effect("looks up shell stop requests through the interrupt request index", () => + it.effect("looks up shell stop requests and active runs through their indexes", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStore.ProjectionStoreV2; const sql = yield* SqlClient.SqlClient; @@ -4355,15 +4355,23 @@ it.layer(layerTest)("ProjectionStoreV2", (it) => { statement.includes("AS latest_run_stop_requested"), ); assert.isDefined(threadQuery); - const stopRequestLookups = (yield* sql.unsafe<{ readonly detail: string }>( + const plan = (yield* sql.unsafe<{ readonly detail: string }>( `EXPLAIN QUERY PLAN ${threadQuery}`, - )) - .map((row) => row.detail) - .filter((detail) => detail.startsWith("SEARCH stop_request ")); + )).map((row) => row.detail); + const stopRequestLookups = plan.filter((detail) => detail.startsWith("SEARCH stop_request ")); assert.lengthOf(stopRequestLookups, 2); for (const lookup of stopRequestLookups) { assert.include(lookup, "orchestration_v2_projection_turn_items_stop_request_idx"); } + // The active, activity, and pending-secret lookups; walking the ordinal index instead + // reads every run of an idle thread. + const activeRunLookups = plan.filter( + (detail) => detail.startsWith("SEARCH r ") && detail.includes("(thread_id=?"), + ); + assert.lengthOf(activeRunLookups, 4); + for (const lookup of activeRunLookups) { + assert.include(lookup, "orchestration_v2_projection_runs_thread_status_idx"); + } }), ); diff --git a/apps/server/src/orchestration-v2/ProjectionStore.ts b/apps/server/src/orchestration-v2/ProjectionStore.ts index b901ea6b0a49..f1060ffe707d 100644 --- a/apps/server/src/orchestration-v2/ProjectionStore.ts +++ b/apps/server/src/orchestration-v2/ProjectionStore.ts @@ -6217,7 +6217,10 @@ export const layer: Layer.Layer = active.status AS active_run_status, ( SELECT r.status + -- Read active runs by status. Walking the ordinal index to skip this sort + -- reads every run of a thread with none active. FROM orchestration_v2_projection_runs r + INDEXED BY orchestration_v2_projection_runs_thread_status_idx WHERE r.thread_id = t.thread_id AND r.status IN ('preparing', 'starting', 'running', 'waiting') AND NOT ${isSilentShellRun("r")} @@ -6232,6 +6235,7 @@ export const layer: Layer.Layer = r.requested_at ) FROM orchestration_v2_projection_runs r + INDEXED BY orchestration_v2_projection_runs_thread_status_idx WHERE r.thread_id = t.thread_id AND r.status IN ('preparing', 'starting', 'running', 'waiting') AND NOT ${isSilentShellRun("r")} @@ -6293,6 +6297,7 @@ export const layer: Layer.Layer = SELECT secret.payload_json -- Keep runs outermost so completed history is never scanned for a pending secret. FROM orchestration_v2_projection_runs r + INDEXED BY orchestration_v2_projection_runs_thread_status_idx CROSS JOIN orchestration_v2_projection_turn_items secret INDEXED BY orchestration_v2_projection_turn_items_thread_run_idx WHERE r.thread_id = t.thread_id @@ -6341,6 +6346,7 @@ export const layer: Layer.Layer = LEFT JOIN orchestration_v2_projection_runs active ON active.run_id = ( SELECT r.run_id FROM orchestration_v2_projection_runs r + INDEXED BY orchestration_v2_projection_runs_thread_status_idx WHERE r.thread_id = t.thread_id AND r.status IN ('preparing', 'starting', 'running') AND NOT ${isSilentShellRun("r")}