From 6a1a18b93f123aff5919f36177860be13b6e506a Mon Sep 17 00:00:00 2001 From: Amp Date: Thu, 30 Jul 2026 22:08:32 +0000 Subject: [PATCH] fix(frontend): submit Vercel drain grace period Amp-Thread-ID: https://ampcode.com/threads/T-019fb4f3-1030-753b-a68e-b440c9b316ac --- .../connect-manual-serverless-frame.tsx | 1 + .../dialogs/connect-quick-vercel-frame.tsx | 6 ++--- .../src/app/dialogs/connect-vercel-frame.tsx | 7 +++--- .../app/forms/connect-quick-vercel-form.tsx | 12 ++++++---- .../src/app/forms/connect-vercel-form.tsx | 23 ++++++++++++++++--- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/frontend/src/app/dialogs/connect-manual-serverless-frame.tsx b/frontend/src/app/dialogs/connect-manual-serverless-frame.tsx index f5badc696e..ee539aedde 100644 --- a/frontend/src/app/dialogs/connect-manual-serverless-frame.tsx +++ b/frontend/src/app/dialogs/connect-manual-serverless-frame.tsx @@ -188,6 +188,7 @@ export const buildServerlessConfig = async ( slotsPerRunner: values.slotsPerRunner ?? 1, runnersMargin: values.runnerMargin ?? 0, minRunners: values.minRunners ?? 0, + drainGracePeriod: values.drainGracePeriod, }; const resolvedProvider = provider || "custom"; const isCustom = diff --git a/frontend/src/app/dialogs/connect-quick-vercel-frame.tsx b/frontend/src/app/dialogs/connect-quick-vercel-frame.tsx index 71ec78dca7..4dd69f5745 100644 --- a/frontend/src/app/dialogs/connect-quick-vercel-frame.tsx +++ b/frontend/src/app/dialogs/connect-quick-vercel-frame.tsx @@ -18,7 +18,6 @@ import { buildServerlessConfig, ConfigurationAccordion, } from "./connect-manual-serverless-frame"; -import { VERCEL_SERVERLESS_MAX_DURATION } from "./connect-vercel-frame"; const { stepper } = ConnectVercelForm; @@ -91,7 +90,8 @@ function FormStepper({ provider, { ...values, - requestLifespan: VERCEL_SERVERLESS_MAX_DURATION - 5, + requestLifespan: + ConnectVercelForm.VERCEL_REQUEST_LIFESPAN, }, { provider: "vercel" }, ); @@ -104,7 +104,7 @@ function FormStepper({ defaultValues={{ runnerName: "default", headers: [], - drainGracePeriod: 0, + drainGracePeriod: ConnectVercelForm.VERCEL_DRAIN_GRACE_PERIOD, plan: "hobby", datacenters: Object.fromEntries( datacenters.map((dc) => [dc.name, true]), diff --git a/frontend/src/app/dialogs/connect-vercel-frame.tsx b/frontend/src/app/dialogs/connect-vercel-frame.tsx index 255e04fe00..97e3b50601 100644 --- a/frontend/src/app/dialogs/connect-vercel-frame.tsx +++ b/frontend/src/app/dialogs/connect-vercel-frame.tsx @@ -19,8 +19,6 @@ import { const { stepper } = ConnectVercelForm; -export const VERCEL_SERVERLESS_MAX_DURATION = 300; - interface CreateProjectFrameContentProps extends DialogContentProps {} export default function CreateProjectFrameContent({ @@ -93,7 +91,8 @@ function FormStepper({ provider, { ...values, - requestLifespan: VERCEL_SERVERLESS_MAX_DURATION - 5, + requestLifespan: + ConnectVercelForm.VERCEL_REQUEST_LIFESPAN, }, { provider: "vercel" }, ); @@ -106,7 +105,7 @@ function FormStepper({ defaultValues={{ plan: "hobby", runnerName: "default", - drainGracePeriod: 0, + drainGracePeriod: ConnectVercelForm.VERCEL_DRAIN_GRACE_PERIOD, headers: [], datacenters: Object.fromEntries( datacenters.map((dc) => [dc.name, true]), diff --git a/frontend/src/app/forms/connect-quick-vercel-form.tsx b/frontend/src/app/forms/connect-quick-vercel-form.tsx index 0617703ab4..3839255509 100644 --- a/frontend/src/app/forms/connect-quick-vercel-form.tsx +++ b/frontend/src/app/forms/connect-quick-vercel-form.tsx @@ -1,10 +1,12 @@ import z from "zod"; import * as ConnectVercelForm from "@/app/forms/connect-vercel-form"; import { defineStepper } from "@/components/ui/stepper"; -import { - configurationSchema, - deploymentSchema, -} from "./connect-manual-serverless-form"; +import { deploymentSchema } from "./connect-manual-serverless-form"; + +export const VERCEL_REQUEST_LIFESPAN = + ConnectVercelForm.VERCEL_REQUEST_LIFESPAN; +export const VERCEL_DRAIN_GRACE_PERIOD = + ConnectVercelForm.VERCEL_DRAIN_GRACE_PERIOD; export const stepper = defineStepper( { @@ -20,7 +22,7 @@ export const stepper = defineStepper( assist: true, next: "Done", schema: z.object({ - ...configurationSchema.omit({ requestLifespan: true }).shape, + ...ConnectVercelForm.configurationSchema.shape, ...deploymentSchema.shape, plan: z.string().min(1, "Please select a Vercel plan"), }), diff --git a/frontend/src/app/forms/connect-vercel-form.tsx b/frontend/src/app/forms/connect-vercel-form.tsx index e5225378bb..60ef1e2ff5 100644 --- a/frontend/src/app/forms/connect-vercel-form.tsx +++ b/frontend/src/app/forms/connect-vercel-form.tsx @@ -24,6 +24,25 @@ import { useRivetDsn, } from "../env-variables"; +export const VERCEL_SERVERLESS_MAX_DURATION = 300; +export const VERCEL_REQUEST_LIFESPAN = VERCEL_SERVERLESS_MAX_DURATION - 5; +export const VERCEL_DRAIN_GRACE_PERIOD = 5; + +export const configurationSchema = + ConnectManualServerlessForm.configurationSchema + .omit({ requestLifespan: true }) + .extend({ + drainGracePeriod: z.coerce + .number() + .min(0) + .max( + VERCEL_REQUEST_LIFESPAN - 1, + `Must be less than ${VERCEL_REQUEST_LIFESPAN}`, + ) + .optional() + .default(VERCEL_DRAIN_GRACE_PERIOD), + }); + export const stepper = defineStepper( { id: "api-route", @@ -55,9 +74,7 @@ export const stepper = defineStepper( next: "Done", schema: z.object({ ...ConnectManualServerlessForm.deploymentSchema.shape, - ...ConnectManualServerlessForm.configurationSchema.omit({ - requestLifespan: true, - }).shape, + ...configurationSchema.shape, plan: z.string().min(1, "Please select a Vercel plan"), }), },