Skip to content

Commit 31999af

Browse files
authored
perf(webapp): trim BackgroundWorker.metadata to the schedule slice on create (#3525)
Large deploys (projects with many tasks or source files) blocked the webapp event loop for several seconds inside Prisma's client-side serializer on `BackgroundWorker.create`, tail-latencying every other in-flight request on the same Node process. The `metadata` JSON column was being written with the full deploy manifest — every task's config, every queue and prompt, and the full source of every file — all of which already live on dedicated columns or in dedicated tables. Fix: project the manifest to `{ packageVersion, contentHash, tasks: [{ id, filePath, schedule }] }` on insert. The only post-write read site is `changeCurrentDeployment`, which feeds `tasks[].schedule` into `syncDeclarativeSchedules` at deploy promotion. The retained top-level keys and per-task `filePath` are kept solely so `BackgroundWorkerMetadata.safeParse` still succeeds on read. ## Test plan - [ ] Deploy a project with declarative schedules; verify schedules are created on first deploy - [ ] Modify / remove schedules across subsequent deploys; verify sync - [ ] Roll back to a previous deploy; verify `changeCurrentDeployment` re-syncs schedules - [ ] Inspect `BackgroundWorker.metadata` on a fresh deploy — should be a small object, not the full manifest
1 parent 14920ce commit 31999af

4 files changed

Lines changed: 43 additions & 9 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: improvement
4+
---
5+
6+
Strip BackgroundWorker.metadata to the schedule slice read at deploy promotion, removing a 5+ second event-loop block in Prisma's client serializer when creating workers for projects with many tasks or source files.

apps/webapp/app/v3/services/createBackgroundWorker.server.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,32 @@ import { tryCatch } from "@trigger.dev/core/v3";
2929
import { engine } from "../runEngine.server";
3030
import { scheduleEngine } from "../scheduleEngine.server";
3131

32+
/**
33+
* Strip BackgroundWorkerMetadata down to the slice that's actually read after
34+
* storage. Everything else is duplicated to dedicated columns/tables
35+
* (BackgroundWorker.{contentHash,cliVersion,sdkVersion,runtime,runtimeVersion},
36+
* BackgroundWorkerTask, BackgroundWorkerFile, TaskQueue, Prompt). Today the
37+
* only post-write reader is changeCurrentDeployment.server.ts, which feeds
38+
* tasks[].schedule into syncDeclarativeSchedules. packageVersion, contentHash,
39+
* and tasks[].filePath are kept solely to satisfy BackgroundWorkerMetadata's
40+
* required fields when the column is parsed back.
41+
*/
42+
export function stripBackgroundWorkerMetadataForStorage(
43+
metadata: BackgroundWorkerMetadata
44+
): Prisma.InputJsonValue {
45+
return {
46+
packageVersion: metadata.packageVersion,
47+
contentHash: metadata.contentHash,
48+
tasks: metadata.tasks
49+
.filter((t) => t.schedule)
50+
.map((t) => ({
51+
id: t.id,
52+
filePath: t.filePath,
53+
schedule: t.schedule,
54+
})),
55+
};
56+
}
57+
3258
export class CreateBackgroundWorkerService extends BaseService {
3359
public async call(
3460
projectRef: string,
@@ -79,8 +105,7 @@ export class CreateBackgroundWorkerService extends BaseService {
79105
version: nextVersion,
80106
runtimeEnvironmentId: environment.id,
81107
projectId: project.id,
82-
// body.metadata has an index signature that Prisma doesn't like (from the JSONSchema type) so we are safe to just cast it
83-
metadata: body.metadata as Prisma.InputJsonValue,
108+
metadata: stripBackgroundWorkerMetadataForStorage(body.metadata),
84109
contentHash: body.metadata.contentHash,
85110
cliVersion: body.metadata.cliPackageVersion,
86111
sdkVersion: body.metadata.packageVersion,

apps/webapp/app/v3/services/createDeploymentBackgroundWorkerV3.server.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { CreateBackgroundWorkerRequestBody, tryCatch } from "@trigger.dev/core/v3";
2-
import type { BackgroundWorker, Prisma } from "@trigger.dev/database";
2+
import type { BackgroundWorker } from "@trigger.dev/database";
33
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
44
import { logger } from "~/services/logger.server";
55
import { syncTaskIdentifiers } from "~/services/taskIdentifierRegistry.server";
66
import { socketIo } from "../handleSocketIo.server";
77
import { updateEnvConcurrencyLimits } from "../runQueue.server";
88
import { PerformDeploymentAlertsService } from "./alerts/performDeploymentAlerts.server";
99
import { BaseService } from "./baseService.server";
10-
import { createWorkerResources, syncDeclarativeSchedules } from "./createBackgroundWorker.server";
10+
import {
11+
createWorkerResources,
12+
stripBackgroundWorkerMetadataForStorage,
13+
syncDeclarativeSchedules,
14+
} from "./createBackgroundWorker.server";
1115
import { ExecuteTasksWaitingForDeployService } from "./executeTasksWaitingForDeploy";
1216
import { projectPubSub } from "./projectPubSub.server";
1317
import { TimeoutDeploymentService } from "./timeoutDeployment.server";
@@ -49,8 +53,7 @@ export class CreateDeploymentBackgroundWorkerServiceV3 extends BaseService {
4953
version: deployment.version,
5054
runtimeEnvironmentId: environment.id,
5155
projectId: environment.projectId,
52-
// body.metadata has an index signature that Prisma doesn't like (from the JSONSchema type) so we are safe to just cast it
53-
metadata: body.metadata as Prisma.InputJsonValue,
56+
metadata: stripBackgroundWorkerMetadataForStorage(body.metadata),
5457
contentHash: body.metadata.contentHash,
5558
cliVersion: body.metadata.cliPackageVersion,
5659
sdkVersion: body.metadata.packageVersion,

apps/webapp/app/v3/services/createDeploymentBackgroundWorkerV4.server.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { CreateBackgroundWorkerRequestBody, logger, tryCatch } from "@trigger.dev/core/v3";
22
import { BackgroundWorkerId } from "@trigger.dev/core/v3/isomorphic";
3-
import type { BackgroundWorker, Prisma, WorkerDeployment } from "@trigger.dev/database";
3+
import type { BackgroundWorker, WorkerDeployment } from "@trigger.dev/database";
44
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
55
import { BaseService, ServiceValidationError } from "./baseService.server";
66
import {
77
createBackgroundFiles,
88
createWorkerResources,
9+
stripBackgroundWorkerMetadataForStorage,
910
syncDeclarativeSchedules,
1011
} from "./createBackgroundWorker.server";
1112
import { TimeoutDeploymentService } from "./timeoutDeployment.server";
@@ -65,8 +66,7 @@ export class CreateDeploymentBackgroundWorkerServiceV4 extends BaseService {
6566
version: deployment.version,
6667
runtimeEnvironmentId: environment.id,
6768
projectId: environment.projectId,
68-
// body.metadata has an index signature that Prisma doesn't like (from the JSONSchema type) so we are safe to just cast it
69-
metadata: body.metadata as Prisma.InputJsonValue,
69+
metadata: stripBackgroundWorkerMetadataForStorage(body.metadata),
7070
contentHash: body.metadata.contentHash,
7171
cliVersion: body.metadata.cliPackageVersion,
7272
sdkVersion: body.metadata.packageVersion,

0 commit comments

Comments
 (0)