Skip to content

Commit f791619

Browse files
d-csclaude
andcommitted
refactor(run-ops): drop known-migrated from read presenters; id-shape only
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 57b0b0a commit f791619

12 files changed

Lines changed: 29 additions & 501 deletions

apps/webapp/app/presenters/v3/ApiBatchResultsPresenter.server.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { BatchTaskRunExecutionResult } from "@trigger.dev/core/v3";
22
import { $replica, PrismaClientOrTransaction, PrismaReplicaClient, prisma } from "~/db.server";
33
import { executionResultForTaskRun, TaskRunWithAttempts } from "~/models/taskRun.server";
44
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
5-
import { isKnownMigrated as defaultIsKnownMigrated } from "~/v3/runOpsMigration/knownMigratedFilter.server";
65
import { readThroughRun } from "~/v3/runOpsMigration/readThrough.server";
76
import { runStore as defaultRunStore } from "~/v3/runStore.server";
87
import { BasePresenter } from "./basePresenter.server";
@@ -15,7 +14,6 @@ type ApiBatchResultsReadThroughDeps = {
1514
splitEnabled?: boolean;
1615
newClient?: PrismaReplicaClient;
1716
legacyReplica?: PrismaReplicaClient;
18-
isKnownMigrated?: (runId: string) => Promise<boolean>;
1917
isPastRetention?: (runId: string) => boolean;
2018
};
2119

@@ -193,7 +191,6 @@ export class ApiBatchResultsPresenter extends BasePresenter {
193191
// own module-level defaults would diverge from the batch read's `?? this._replica`.)
194192
newClient,
195193
legacyReplica,
196-
isKnownMigrated: this.readThrough?.isKnownMigrated ?? defaultIsKnownMigrated,
197194
isPastRetention: this.readThrough?.isPastRetention,
198195
},
199196
});

apps/webapp/app/presenters/v3/ApiRunResultPresenter.server.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ type ApiRunResultReadThroughDeps = {
1010
newClient?: PrismaReplicaClient;
1111
// LEGACY RUN-OPS READ REPLICA ONLY (never a writer/primary); defaults to this._replica.
1212
legacyReplica?: PrismaReplicaClient;
13-
isKnownMigrated?: (runId: string) => Promise<boolean>;
1413
isPastRetention?: (runId: string) => boolean;
1514
};
1615

@@ -35,7 +34,7 @@ export class ApiRunResultPresenter extends BasePresenter {
3534
});
3635

3736
// Single-run result poll routed through run-ops read-through. Split on: primary store first,
38-
// then the secondary read replica only for runs not known-migrated; past-retention ids return
37+
// then the secondary read replica for runs that miss on new; past-retention ids return
3938
// undefined -> the route's normal 404. Split off (single-DB / self-host): readThroughRun does
4039
// one plain findFirst against the single client (passthrough).
4140
const result = await readThroughRun({
@@ -47,7 +46,6 @@ export class ApiRunResultPresenter extends BasePresenter {
4746
splitEnabled: this._readThrough?.splitEnabled,
4847
newClient: this._readThrough?.newClient ?? (this._prisma as PrismaReplicaClient),
4948
legacyReplica: this._readThrough?.legacyReplica ?? (this._replica as PrismaReplicaClient),
50-
isKnownMigrated: this._readThrough?.isKnownMigrated,
5149
isPastRetention: this._readThrough?.isPastRetention,
5250
},
5351
});

apps/webapp/app/presenters/v3/ApiWaitpointPresenter.server.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ import { waitpointStatusToApiStatus } from "./WaitpointListPresenter.server";
66
import { generateHttpCallbackUrl } from "~/services/httpCallback.server";
77
import type { PrismaClientOrTransaction, PrismaReplicaClient } from "~/db.server";
88
import { readThroughRun } from "~/v3/runOpsMigration/readThrough.server";
9-
import { isKnownMigrated } from "~/v3/runOpsMigration/knownMigratedFilter.server";
109

1110
// When omitted, clients default to the inherited _replica handle => passthrough reads the
12-
// replica exactly as today. Pure boundaries (isKnownMigrated/isPastRetention) are injectable
13-
// for tests. Typed PrismaReplicaClient to match readThroughRun's readNew/readLegacy + deps.
11+
// replica exactly as today. isPastRetention is injectable for tests. Typed PrismaReplicaClient
12+
// to match readThroughRun's readNew/readLegacy + deps.
1413
type ApiWaitpointPresenterReadThroughDeps = {
1514
newClient?: PrismaReplicaClient;
1615
legacyReplica?: PrismaReplicaClient;
1716
splitEnabled?: boolean;
18-
isKnownMigrated?: (id: string) => Promise<boolean>;
1917
isPastRetention?: (id: string) => boolean;
2018
};
2119

@@ -42,7 +40,7 @@ export class ApiWaitpointPresenter extends BasePresenter {
4240
) {
4341
return this.trace("call", async (span) => {
4442
// Public waitpoint retrieve. Split on: new run-ops client first, then the LEGACY
45-
// RUN-OPS READ REPLICA ONLY for ids not known-migrated — never the legacy primary.
43+
// RUN-OPS READ REPLICA ONLY on a new-probe miss — never the legacy primary.
4644
// Split off (single-DB / self-host): one plain waitpoint.findFirst against the replica
4745
// (passthrough). The waitpointId is the residency-classifiable KSUID id (the route
4846
// pre-decodes the friendlyId via WaitpointId.toId).
@@ -90,7 +88,6 @@ export class ApiWaitpointPresenter extends BasePresenter {
9088
newClient: this.readThroughDeps?.newClient ?? (this._replica as PrismaReplicaClient),
9189
legacyReplica:
9290
this.readThroughDeps?.legacyReplica ?? (this._replica as PrismaReplicaClient),
93-
isKnownMigrated: this.readThroughDeps?.isKnownMigrated ?? isKnownMigrated,
9491
isPastRetention: this.readThroughDeps?.isPastRetention,
9592
},
9693
});

apps/webapp/app/presenters/v3/TestTaskPresenter.server.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { type PrismaClient } from "~/db.server";
1414
import { RunsRepository } from "~/services/runsRepository/runsRepository.server";
1515
import { getTimezones } from "~/utils/timezones.server";
1616
import { findCurrentWorkerDeployment } from "~/v3/models/workerDeployment.server";
17-
import { isKnownMigrated as defaultIsKnownMigrated } from "~/v3/runOpsMigration/knownMigratedFilter.server";
1817
import { runStore as defaultRunStore } from "~/v3/runStore.server";
1918
import { queueTypeFromType } from "./QueueRetrievePresenter.server";
2019

@@ -26,7 +25,6 @@ type TestTaskReadThroughDeps = {
2625
legacyReplica?: PrismaClientOrTransaction;
2726
// Resolved boot constant; when false the split branch is never entered.
2827
splitEnabled?: boolean;
29-
isKnownMigrated?: (runId: string) => Promise<boolean>;
3028
};
3129

3230
// The byte-identical select the recent-payloads hydrate has always used; `id` is
@@ -414,7 +412,7 @@ export class TestTaskPresenter {
414412
}
415413

416414
// Hydrates the recent-payloads run-id set from the run-ops store. Split on: new
417-
// client first, then the LEGACY READ REPLICA ONLY for ids not known-migrated
415+
// client first, then the LEGACY READ REPLICA ONLY for ids that miss on new
418416
// never the legacy primary. Split off: one plain findRuns on `this.replica`.
419417
private async hydrateRecentRuns(runIds: string[]): Promise<RecentRunRow[]> {
420418
if (runIds.length === 0) {
@@ -427,18 +425,11 @@ export class TestTaskPresenter {
427425

428426
const newClient = this.readThrough.newClient ?? this.replica;
429427
const legacyReplica = this.readThrough.legacyReplica ?? this.replica;
430-
const isKnownMigrated = this.readThrough.isKnownMigrated ?? defaultIsKnownMigrated;
431428

432429
const newRows = await this.hydrateOnClient(newClient, runIds);
433430
const foundIds = new Set(newRows.map((r) => r.id));
434-
const missing = runIds.filter((id) => !foundIds.has(id));
435-
436-
const toProbeLegacy: string[] = [];
437-
for (const id of missing) {
438-
if (!(await isKnownMigrated(id))) {
439-
toProbeLegacy.push(id);
440-
}
441-
}
431+
// Probe every id that missed on new against the legacy read replica.
432+
const toProbeLegacy = runIds.filter((id) => !foundIds.has(id));
442433

443434
const legacyRows = toProbeLegacy.length
444435
? await this.hydrateOnClient(legacyReplica, toProbeLegacy)

apps/webapp/app/presenters/v3/WaitpointPresenter.server.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstan
99
import { generateHttpCallbackUrl } from "~/services/httpCallback.server";
1010
import { logger } from "~/services/logger.server";
1111
import { controlPlaneResolver } from "~/v3/runOpsMigration/controlPlaneResolver.server";
12-
import { isKnownMigrated } from "~/v3/runOpsMigration/knownMigratedFilter.server";
1312
import { readThroughRun } from "~/v3/runOpsMigration/readThrough.server";
1413
import { BasePresenter } from "./basePresenter.server";
1514
import { NextRunListPresenter, type NextRunListItem } from "./NextRunListPresenter.server";
@@ -29,7 +28,6 @@ export class WaitpointPresenter extends BasePresenter {
2928
// Resolved boot constant from isSplitEnabled(). When false/absent:
3029
// the waitpoint lookup is one plain findFirst and the connected-runs hydrate runs passthrough.
3130
splitEnabled?: boolean;
32-
isKnownMigrated?: (id: string) => Promise<boolean>;
3331
}
3432
) {
3533
super(prisma, replica);
@@ -80,7 +78,6 @@ export class WaitpointPresenter extends BasePresenter {
8078
legacyReplica:
8179
(this.readThroughDeps.legacyReplica as PrismaReplicaClient | undefined) ??
8280
runOpsLegacyReplica,
83-
isKnownMigrated: this.readThroughDeps.isKnownMigrated ?? isKnownMigrated,
8481
},
8582
});
8683

apps/webapp/test/apiBatchResultsPresenter.readthrough.test.ts

Lines changed: 2 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// REPLICA ONLY; each member run is hydrated independently via the per-run read-through primitive,
55
// so a batch whose members span migrated (NEW) + abandoned (LEGACY) runs returns the
66
// complete reachable set. Single-DB collapses to one passthrough read. We NEVER mock the DB — the
7-
// only injected fakes are the pure boundaries (splitEnabled / isKnownMigrated / isPastRetention).
7+
// only injected fakes are the pure boundaries (splitEnabled / isPastRetention).
88
//
99
// The BatchTaskRunItem -> TaskRun FK is per-DB; a batch straddling the seam references member ids
1010
// that live on the other DB, so we drop that one FK on the batch's DB at seed time (the cross-seam
@@ -196,8 +196,6 @@ const env = (ctx: SeedCtx) =>
196196
project: { name: ctx.project.name },
197197
}) as unknown as AuthenticatedEnvironment;
198198

199-
const neverMigrated = async () => false;
200-
201199
describe("ApiBatchResultsPresenter read-through (legacy + new DB)", () => {
202200
// A batch with members on BOTH DBs returns the complete set, byte-identical.
203201
heteroPostgresTest(
@@ -235,7 +233,6 @@ describe("ApiBatchResultsPresenter read-through (legacy + new DB)", () => {
235233
splitEnabled: true,
236234
newClient: prisma17 as unknown as PrismaReplicaClient,
237235
legacyReplica: prisma14 as unknown as PrismaReplicaClient,
238-
isKnownMigrated: neverMigrated,
239236
});
240237

241238
const result = await presenter.call("batch_span", env(ctx));
@@ -286,7 +283,6 @@ describe("ApiBatchResultsPresenter read-through (legacy + new DB)", () => {
286283
splitEnabled: true,
287284
newClient: prisma17 as unknown as PrismaReplicaClient,
288285
legacyReplica: prisma14 as unknown as PrismaReplicaClient,
289-
isKnownMigrated: neverMigrated,
290286
});
291287

292288
const result = await presenter.call("batch_legacy", env(ctx));
@@ -298,69 +294,6 @@ describe("ApiBatchResultsPresenter read-through (legacy + new DB)", () => {
298294
}
299295
);
300296

301-
// A known-migrated member is not re-probed against the legacy replica.
302-
heteroPostgresTest(
303-
"a known-migrated member missing from the new probe is NOT re-probed on legacy",
304-
async ({ prisma14, prisma17 }) => {
305-
const newDb = prisma17 as unknown as PrismaClient;
306-
const legacyDb = prisma14 as unknown as PrismaClient;
307-
308-
const ctx = await seedEnv(newDb, "mig-new");
309-
await mirrorEnv(legacyDb, ctx, "mig-legacy");
310-
await relaxFks(newDb);
311-
await relaxFks(legacyDb);
312-
313-
// A legacy-classified id (so the LEGACY fan-out branch is reachable) that is "known migrated".
314-
const migratedId = legacyRunId("d");
315-
// Seed the member ONLY on legacy, but mark it known-migrated → legacy must NOT be probed,
316-
// so it resolves to not-found and is omitted.
317-
await seedMember(legacyDb, ctx, {
318-
id: migratedId,
319-
friendlyId: "run_migrated_d",
320-
status: "COMPLETED_SUCCESSFULLY",
321-
output: JSON.stringify({}),
322-
});
323-
await seedBatch(newDb, ctx, "batch_mig", [migratedId]);
324-
325-
// Spy legacy replica: throw if the member-hydrate findFirst runs for the migrated id.
326-
const legacySpy = new Proxy(prisma14, {
327-
get(target, prop) {
328-
if (prop === "taskRun") {
329-
return new Proxy((target as any).taskRun, {
330-
get(trTarget, trProp) {
331-
if (trProp === "findFirst") {
332-
return async (args: any) => {
333-
if (args?.where?.id === migratedId) {
334-
throw new Error(
335-
"legacy replica must not be probed for a known-migrated member"
336-
);
337-
}
338-
return (trTarget as any).findFirst(args);
339-
};
340-
}
341-
return (trTarget as any)[trProp];
342-
},
343-
});
344-
}
345-
return (target as any)[prop];
346-
},
347-
}) as unknown as PrismaReplicaClient;
348-
349-
const presenter = new ApiBatchResultsPresenter(throwingPrisma, throwingPrisma, {
350-
splitEnabled: true,
351-
newClient: prisma17 as unknown as PrismaReplicaClient,
352-
legacyReplica: legacySpy,
353-
isKnownMigrated: async (id) => id === migratedId,
354-
});
355-
356-
const result = await presenter.call("batch_mig", env(ctx));
357-
358-
expect(result).toBeDefined();
359-
// Known-migrated + missing from NEW → not-found → omitted, without probing legacy.
360-
expect(result!.items).toHaveLength(0);
361-
}
362-
);
363-
364297
// Past-retention / missing member is omitted (dangling-ref gate adjacent), not errored.
365298
heteroPostgresTest(
366299
"a member present on neither DB is omitted; the reachable members still return",
@@ -388,7 +321,6 @@ describe("ApiBatchResultsPresenter read-through (legacy + new DB)", () => {
388321
splitEnabled: true,
389322
newClient: prisma17 as unknown as PrismaReplicaClient,
390323
legacyReplica: prisma14 as unknown as PrismaReplicaClient,
391-
isKnownMigrated: neverMigrated,
392324
});
393325

394326
const result = await presenter.call("batch_dangle", env(ctx));
@@ -411,7 +343,6 @@ describe("ApiBatchResultsPresenter read-through (legacy + new DB)", () => {
411343
splitEnabled: true,
412344
newClient: prisma17 as unknown as PrismaReplicaClient,
413345
legacyReplica: prisma14 as unknown as PrismaReplicaClient,
414-
isKnownMigrated: neverMigrated,
415346
});
416347

417348
const result = await presenter.call("batch_does_not_exist", env(ctx));
@@ -439,16 +370,13 @@ describe("ApiBatchResultsPresenter passthrough (single-DB collapse)", () => {
439370

440371
const runStore = new PostgresRunStore({ prisma, readOnlyPrisma: prisma });
441372

442-
// Throwing boundaries: if the split path is entered, these blow up.
373+
// Throwing legacy replica: if the split path is entered, it blows up.
443374
const presenter = new ApiBatchResultsPresenter(
444375
prisma,
445376
prisma,
446377
{
447378
splitEnabled: false,
448379
legacyReplica: throwingPrisma,
449-
isKnownMigrated: async () => {
450-
throw new Error("isKnownMigrated must not be invoked on the passthrough path");
451-
},
452380
},
453381
runStore
454382
);

0 commit comments

Comments
 (0)