11import type { PrismaReplicaClient } from "~/db.server" ;
22import {
33 $replica as defaultLegacyReplica ,
4+ runOpsLegacyPrisma as defaultLegacyPrimary ,
5+ runOpsNewPrisma as defaultNewPrimary ,
46 runOpsNewReplica as defaultNewClient ,
57 runOpsSplitReadEnabled as defaultSplitReadEnabled ,
68} from "~/db.server" ;
@@ -9,6 +11,8 @@ import { readThroughRun } from "~/v3/runOpsMigration/readThrough.server";
911type ResolveWaitpointDeps = {
1012 newClient ?: PrismaReplicaClient ;
1113 legacyReplica ?: PrismaReplicaClient ;
14+ newPrimary ?: PrismaReplicaClient ;
15+ legacyPrimary ?: PrismaReplicaClient ;
1216 splitEnabled ?: boolean ;
1317 isPastRetention ?: ( id : string ) => boolean ;
1418} ;
@@ -18,12 +22,16 @@ type ResolveWaitpointDeps = {
1822export type ResolveWaitpointReadThroughDefaults = {
1923 newClient : PrismaReplicaClient ;
2024 legacyReplica : PrismaReplicaClient ;
25+ newPrimary : PrismaReplicaClient ;
26+ legacyPrimary : PrismaReplicaClient ;
2127 splitEnabled : boolean ;
2228} ;
2329
2430const productionDefaults : ResolveWaitpointReadThroughDefaults = {
2531 newClient : defaultNewClient ,
2632 legacyReplica : defaultLegacyReplica ,
33+ newPrimary : defaultNewPrimary as unknown as PrismaReplicaClient ,
34+ legacyPrimary : defaultLegacyPrimary as unknown as PrismaReplicaClient ,
2735 splitEnabled : defaultSplitReadEnabled ,
2836} ;
2937
@@ -36,18 +44,42 @@ export async function resolveWaitpointThroughReadThrough<T>(opts: {
3644} ) : Promise < T | null > {
3745 const defaults = opts . defaults ?? productionDefaults ;
3846
47+ const splitEnabled = opts . deps ?. splitEnabled ?? defaults . splitEnabled ;
48+
3949 const result = await readThroughRun ( {
4050 runId : opts . waitpointId ,
4151 environmentId : opts . environmentId ,
4252 readNew : ( client ) => opts . read ( client ) ,
4353 readLegacy : ( replica ) => opts . read ( replica ) ,
4454 deps : {
45- splitEnabled : opts . deps ?. splitEnabled ?? defaults . splitEnabled ,
55+ splitEnabled,
4656 newClient : opts . deps ?. newClient ?? defaults . newClient ,
4757 legacyReplica : opts . deps ?. legacyReplica ?? defaults . legacyReplica ,
4858 isPastRetention : opts . deps ?. isPastRetention ,
4959 } ,
5060 } ) ;
5161
52- return result . source === "new" || result . source === "legacy-replica" ? result . value : null ;
62+ if ( result . source === "new" || result . source === "legacy-replica" ) {
63+ return result . value ;
64+ }
65+ // past-retention is an intentional not-found: the token is gone, don't hit the primary.
66+ if ( result . source === "past-retention" ) {
67+ return null ;
68+ }
69+
70+ // Read-your-writes fallback: readThroughRun is replica-only, so a token completed immediately after
71+ // it was minted can miss on the replicas (not yet applied) and 404 a valid token - and the
72+ // authoritative completeWaitpoint never runs. Re-read from the owning-store PRIMARY (new then legacy)
73+ // before giving up. Bounded to this replica-miss; a genuinely-absent token still returns null.
74+ const fromNewPrimary = await opts . read ( opts . deps ?. newPrimary ?? defaults . newPrimary ) ;
75+ if ( fromNewPrimary != null ) {
76+ return fromNewPrimary ;
77+ }
78+ if ( splitEnabled ) {
79+ const fromLegacyPrimary = await opts . read ( opts . deps ?. legacyPrimary ?? defaults . legacyPrimary ) ;
80+ if ( fromLegacyPrimary != null ) {
81+ return fromLegacyPrimary ;
82+ }
83+ }
84+ return null ;
5385}
0 commit comments