-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
perf(webapp,run-store): grouped run-ops reads + mint-kind flip grace #4227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c642427
e7fb6bd
fc9588f
a32f169
119c1f6
3e8faa5
e205b80
b9bf974
54c79b6
98996c9
2e839a9
32e46e9
8891394
16df23f
bfb9ddf
4660a0a
ce00de1
c60dd3b
bb008c9
9c10e14
7db8e46
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,15 @@ | ||
| import type { ActionFunctionArgs } from "@remix-run/server-runtime"; | ||
| import { json } from "@remix-run/server-runtime"; | ||
| import { prisma } from "~/db.server"; | ||
| import { env } from "~/env.server"; | ||
| import { requireAdminApiRequest } from "~/services/personalAccessToken.server"; | ||
| import { makeSetMultipleFlags } from "~/v3/featureFlags.server"; | ||
| import { validatePartialFeatureFlags } from "~/v3/featureFlags"; | ||
| import { | ||
| FEATURE_FLAG, | ||
| type FeatureFlagCatalog, | ||
| validatePartialFeatureFlags, | ||
| } from "~/v3/featureFlags"; | ||
| import { stampMintKindFlip } from "~/v3/runOpsMigration/mintFlipGrace"; | ||
|
|
||
| export async function action({ request }: ActionFunctionArgs) { | ||
| await requireAdminApiRequest(request); | ||
|
|
@@ -24,9 +30,51 @@ export async function action({ request }: ActionFunctionArgs) { | |
| ); | ||
| } | ||
|
|
||
| const featureFlags = validationResult.data; | ||
| // Derived grace-stamp fields are computed server-side; never trust them from the body. | ||
| const { | ||
| runOpsMintKindPrev: _ignoredPrev, | ||
| runOpsMintKindFlippedAt: _ignoredFlippedAt, | ||
| ...requestedFlags | ||
| } = validationResult.data; | ||
|
|
||
| let flagsToWrite: Partial<FeatureFlagCatalog> = requestedFlags; | ||
|
|
||
| if (requestedFlags.runOpsMintKind !== undefined) { | ||
| // Read the current GLOBAL mint flags so the stamp is computed against the authoritative | ||
| // stored state, mirroring the per-org route. stampMintKindFlip writes prev/flippedAt only | ||
| // on a genuine global flip, and carries an in-flight stamp forward on a same-target save. | ||
| const existingRows = await prisma.featureFlag.findMany({ | ||
| where: { | ||
| key: { | ||
| in: [ | ||
| FEATURE_FLAG.runOpsMintKind, | ||
| FEATURE_FLAG.runOpsMintKindPrev, | ||
| FEATURE_FLAG.runOpsMintKindFlippedAt, | ||
| ], | ||
| }, | ||
| }, | ||
| select: { key: true, value: true }, | ||
| }); | ||
| const existingGlobal: Record<string, unknown> = {}; | ||
| for (const row of existingRows) { | ||
| existingGlobal[row.key] = row.value; | ||
| } | ||
|
|
||
| // Anchor the cutover to the control-plane DB clock, not this process's wall clock. | ||
| const [{ now: controlPlaneNow }] = await prisma.$queryRaw< | ||
| { now: Date }[] | ||
| >`SELECT now() AS now`; | ||
|
|
||
| flagsToWrite = stampMintKindFlip( | ||
| existingGlobal, | ||
| { ...requestedFlags }, | ||
| controlPlaneNow.getTime(), | ||
| env.RUN_OPS_MINT_FLIP_GRACE_MS | ||
| ) as Partial<FeatureFlagCatalog>; | ||
| } | ||
|
|
||
| const setMultipleFlags = makeSetMultipleFlags(prisma); | ||
| const updatedFlags = await setMultipleFlags(featureFlags); | ||
| const updatedFlags = await setMultipleFlags(flagsToWrite); | ||
|
Comment on lines
+46
to
+77
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Concurrent global mint-kind flag flips can clobber each other's grace-window metadata The global feature-flag save reads existing flags and writes the stamped result without a transaction or row lock ( Impact: A lost grace stamp means the deterministic cutover window doesn't fire, briefly reopening the cross-DB duplicate window the grace mechanism was designed to close. Race condition: read-then-write without locking on the global flags routeThe per-org routes at The global flags route at
If two requests race, both read the same Prompt for agentsWas this helpful? React with 👍 or 👎 to provide feedback. |
||
|
|
||
| return json({ | ||
| success: true, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.