Skip to content

Commit 01bc5f7

Browse files
carderneTrigger.dev RepoOps
authored andcommitted
refactor(webapp): remove worker queue feature flag overrides
## Summary Remove the worker queue v2 and scheduled-split feature flag overrides and admin controls. Both behaviours remain controlled by their existing environment variables, with unchanged defaults. Preserve development exclusions, unknown-queue fallback, compatibility/channel selection, and routing for existing executions and restores. Obsolete stored flags are ignored by the existing catalogue validation. Mono-RevId: 9a686dd37689c4950483502ae3a040a1e0d3d6f7
1 parent 9629749 commit 01bc5f7

9 files changed

Lines changed: 83 additions & 162 deletions

‎apps/webapp/app/env.server.ts‎

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,14 +1570,7 @@ const EnvironmentSchema = z
15701570
COMMON_WORKER_REDIS_TLS_DISABLED: z.string().default(process.env.REDIS_TLS_DISABLED ?? "false"),
15711571
COMMON_WORKER_REDIS_CLUSTER_MODE_ENABLED: z.string().default("0"),
15721572

1573-
// Global default for the scheduled worker-queue split. When "1", runs in a
1574-
// scheduled lineage (rootTriggerSource === "schedule") are routed to a
1575-
// dedicated `<region>:scheduled` worker queue so a separate consumer fleet
1576-
// can dequeue them independently of standard/agent runs. The per-org
1577-
// `workerQueueScheduledSplitEnabled` feature flag overrides this default in
1578-
// BOTH directions (an org set to false stays on the single queue even when
1579-
// this is "1"; an org set to true splits even when this is "0"). Never
1580-
// applies to DEVELOPMENT environments.
1573+
// Requires consumers configured for scheduled queues. Never applies to development.
15811574
TRIGGER_WORKER_QUEUE_SCHEDULED_SPLIT_ENABLED: z.string().default("0"),
15821575
// Controls new assignments only; existing v2 runs retain their routing.
15831576
TRIGGER_WORKER_QUEUE_V2_ENABLED: z.string().default("0"),

‎apps/webapp/app/runEngine/concerns/workerQueueAssignment.server.test.ts‎

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,44 @@ const assignment = {
77
region: "us-east-1",
88
envType: "PRODUCTION",
99
orgFeatureFlags: null,
10-
globalDefault: false,
10+
v2Enabled: true,
11+
splitEnabled: true,
1112
workerGroups: [{ masterQueue: "us-east-1-next", workloadType: "MICROVM" as const }],
1213
rootTriggerSource: "api",
13-
splitEnabled: true,
1414
};
1515

1616
describe("workerQueueForBirth", () => {
17-
it("keeps legacy assignment and scheduled lineage when v2 is off", () => {
18-
expect(workerQueueForBirth(assignment)).toBe("us-east-1-next");
19-
expect(workerQueueForBirth({ ...assignment, rootTriggerSource: "schedule" })).toBe(
20-
"us-east-1-next:scheduled"
21-
);
17+
it.each([false, true])(
18+
"keeps legacy assignment when v2 is disabled (split=%s)",
19+
(splitEnabled) => {
20+
expect(
21+
workerQueueForBirth({
22+
...assignment,
23+
workerQueue: "my workers",
24+
region: undefined,
25+
workerGroups: [{ masterQueue: "my workers", workloadType: "CONTAINER" }],
26+
v2Enabled: false,
27+
splitEnabled,
28+
rootTriggerSource: "schedule",
29+
orgFeatureFlags: {
30+
workerQueueV2Enabled: true,
31+
workerQueueScheduledSplitEnabled: true,
32+
},
33+
})
34+
).toBe(splitEnabled ? "my workers:scheduled" : "my workers");
35+
}
36+
);
37+
38+
it("keeps scheduled runs on the ondemand v2 queue when the split is disabled", () => {
39+
expect(
40+
workerQueueForBirth({ ...assignment, splitEnabled: false, rootTriggerSource: "schedule" })
41+
).toBe("us-east-1:v2:ondemand:fresh:compute:stable");
2242
});
2343

2444
it("keeps legacy routing when the selected queue is absent from a loaded registry", () => {
2545
const input = {
2646
...assignment,
2747
region: assignment.workerQueue,
28-
globalDefault: true,
2948
workerGroups: [{ masterQueue: "us-west-2", workloadType: "CONTAINER" as const }],
3049
};
3150
expect(workerQueueForBirth(input)).toBe("us-east-1-next");
@@ -34,25 +53,21 @@ describe("workerQueueForBirth", () => {
3453
);
3554
});
3655

37-
it("uses the geographic region and selected runtime when v2 is enabled", () => {
38-
expect(workerQueueForBirth({ ...assignment, globalDefault: true })).toBe(
39-
"us-east-1:v2:ondemand:fresh:compute:stable"
40-
);
56+
it("uses the geographic region and selected runtime for deployed runs", () => {
57+
expect(workerQueueForBirth(assignment)).toBe("us-east-1:v2:ondemand:fresh:compute:stable");
4158
expect(
4259
workerQueueForBirth({
4360
...assignment,
44-
globalDefault: true,
4561
workerGroups: [{ masterQueue: "us-east-1-next", workloadType: "CONTAINER" }],
4662
})
4763
).toBe("us-east-1:v2:ondemand:fresh:container:stable");
4864
});
4965

50-
it("honors org opt-in, channel and explicit shared-runtime assignment", () => {
66+
it("honors channel and explicit shared-runtime assignment", () => {
5167
expect(
5268
workerQueueForBirth({
5369
...assignment,
5470
orgFeatureFlags: {
55-
[FEATURE_FLAG.workerQueueV2Enabled]: true,
5671
[FEATURE_FLAG.workerQueueCompatibility]: "any",
5772
[FEATURE_FLAG.workerQueueChannel]: "canary",
5873
},
@@ -61,25 +76,29 @@ describe("workerQueueForBirth", () => {
6176
).toBe("us-east-1:v2:scheduled:fresh:any:canary");
6277
});
6378

64-
it("honors org opt-out even when the global default is enabled", () => {
79+
it("ignores obsolete opt-outs for v2 and scheduled assignment", () => {
6580
expect(
6681
workerQueueForBirth({
6782
...assignment,
68-
globalDefault: true,
69-
orgFeatureFlags: { [FEATURE_FLAG.workerQueueV2Enabled]: false },
83+
orgFeatureFlags: {
84+
workerQueueV2Enabled: false,
85+
workerQueueScheduledSplitEnabled: false,
86+
},
87+
rootTriggerSource: "schedule",
7088
})
71-
).toBe("us-east-1-next");
89+
).toBe("us-east-1:v2:scheduled:fresh:compute:stable");
7290
});
7391

74-
it("leaves development on the legacy path even with an org opt-in", () => {
75-
expect(
76-
workerQueueForBirth({
77-
...assignment,
78-
envType: "DEVELOPMENT",
79-
splitEnabled: false,
80-
globalDefault: true,
81-
orgFeatureFlags: { [FEATURE_FLAG.workerQueueV2Enabled]: true },
82-
})
83-
).toBe("us-east-1-next");
84-
});
92+
it.each(["api", "schedule"])(
93+
"leaves development on the base legacy queue for %s",
94+
(rootTriggerSource) => {
95+
expect(
96+
workerQueueForBirth({
97+
...assignment,
98+
envType: "DEVELOPMENT",
99+
rootTriggerSource,
100+
})
101+
).toBe("us-east-1-next");
102+
}
103+
);
85104
});

‎apps/webapp/app/runEngine/concerns/workerQueueAssignment.server.ts‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,27 @@ export function workerQueueForBirth({
88
region,
99
envType,
1010
orgFeatureFlags,
11-
globalDefault,
11+
v2Enabled,
12+
splitEnabled,
1213
workerGroups,
1314
rootTriggerSource,
14-
splitEnabled,
1515
}: {
1616
workerQueue: string;
1717
region: string | undefined;
1818
envType: string;
1919
orgFeatureFlags: Record<string, unknown> | null | undefined;
20-
globalDefault: boolean;
20+
v2Enabled: boolean;
21+
splitEnabled: boolean;
2122
workerGroups: readonly Pick<WorkerGroupRegionRow, "masterQueue" | "workloadType">[];
2223
rootTriggerSource: string | undefined;
23-
splitEnabled: boolean;
2424
}): string {
25-
const enabled = orgFeatureFlags?.[FEATURE_FLAG.workerQueueV2Enabled];
26-
const useV2 =
27-
envType !== "DEVELOPMENT" && (typeof enabled === "boolean" ? enabled : globalDefault);
25+
if (envType === "DEVELOPMENT") {
26+
return workerQueue;
27+
}
2828

2929
// An unknown queue (e.g. cold registry) has no trustworthy region or runtime, so stay legacy.
3030
const group = workerGroups.find((group) => group.masterQueue === workerQueue);
31-
if (!useV2 || !group) {
31+
if (!v2Enabled || !group) {
3232
return workerQueueForRun({ workerQueue, rootTriggerSource, splitEnabled });
3333
}
3434

‎apps/webapp/app/runEngine/concerns/workerQueueSplit.server.ts‎

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
WORKER_QUEUE_VERSION,
55
type WorkerQueueClass,
66
} from "@trigger.dev/core/v3/workers";
7-
import { FEATURE_FLAG, FeatureFlagCatalog } from "~/v3/featureFlags";
87

98
export { SCHEDULED_WORKER_QUEUE_SUFFIX } from "@trigger.dev/core/v3/workers";
109

@@ -45,35 +44,6 @@ export function regionForDisplay(
4544
/** `TriggerSource` value used for runs originating from a schedule. */
4645
const SCHEDULE_TRIGGER_SOURCE = "schedule";
4746

48-
/**
49-
* Resolve whether the scheduled worker-queue split is enabled for a run, reading
50-
* only the in-memory org feature-flags JSON (already loaded on the authenticated
51-
* environment) — never a DB query, so it is safe on the trigger hot path.
52-
*
53-
* Precedence: a per-org override wins in BOTH directions; the global default is
54-
* used only when the org has not set the flag.
55-
*/
56-
export function resolveScheduledQueueSplitEnabled({
57-
orgFeatureFlags,
58-
globalDefault,
59-
}: {
60-
orgFeatureFlags: Record<string, unknown> | null | undefined;
61-
globalDefault: boolean;
62-
}): boolean {
63-
const override = orgFeatureFlags?.[FEATURE_FLAG.workerQueueScheduledSplitEnabled];
64-
65-
if (override !== undefined) {
66-
const parsed =
67-
FeatureFlagCatalog[FEATURE_FLAG.workerQueueScheduledSplitEnabled].safeParse(override);
68-
69-
if (parsed.success) {
70-
return parsed.data;
71-
}
72-
}
73-
74-
return globalDefault;
75-
}
76-
7747
/**
7848
* Pick the worker queue a run should be enqueued onto. Runs in a scheduled
7949
* lineage (`rootTriggerSource === "schedule"`, which propagates from a scheduled

‎apps/webapp/app/runEngine/services/triggerTask.server.ts‎

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import {
4040
type IdempotencyKeyConcern,
4141
type ClaimedIdempotency,
4242
} from "../concerns/idempotencyKeys.server";
43-
import { resolveScheduledQueueSplitEnabled } from "../concerns/workerQueueSplit.server";
4443
import { workerQueueForBirth } from "../concerns/workerQueueAssignment.server";
4544
import { resolveComputeMigration } from "../concerns/computeMigration.server";
4645
import { workerRegionRegistry, backingForQueue, regionForQueue } from "~/v3/workerRegions.server";
@@ -541,17 +540,6 @@ export class RunEngineTriggerTaskService {
541540
webhookEndpointId: options.webhookEndpointId,
542541
};
543542

544-
// Preserve scheduled lineage independently of the queue-name version.
545-
// Rollout decisions use already-loaded org flags and registry data.
546-
const scheduledQueueSplitEnabled =
547-
environment.type !== "DEVELOPMENT" &&
548-
resolveScheduledQueueSplitEnabled({
549-
orgFeatureFlags: environment.organization.featureFlags as Record<
550-
string,
551-
unknown
552-
> | null,
553-
globalDefault: env.TRIGGER_WORKER_QUEUE_SCHEDULED_SPLIT_ENABLED === "1",
554-
});
555543
const workerQueue =
556544
migrated.workerQueue !== undefined
557545
? workerQueueForBirth({
@@ -562,10 +550,10 @@ export class RunEngineTriggerTaskService {
562550
string,
563551
unknown
564552
> | null,
565-
globalDefault: env.TRIGGER_WORKER_QUEUE_V2_ENABLED === "1",
553+
v2Enabled: env.TRIGGER_WORKER_QUEUE_V2_ENABLED === "1",
554+
splitEnabled: env.TRIGGER_WORKER_QUEUE_SCHEDULED_SPLIT_ENABLED === "1",
566555
workerGroups,
567556
rootTriggerSource: annotations.rootTriggerSource,
568-
splitEnabled: scheduledQueueSplitEnabled,
569557
})
570558
: migrated.workerQueue;
571559

‎apps/webapp/app/v3/featureFlags.ts‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ export const FEATURE_FLAG = {
1919
hasSso: "hasSso",
2020
hasThemeSwitcher: "hasThemeSwitcher",
2121
mollifierEnabled: "mollifierEnabled",
22-
workerQueueScheduledSplitEnabled: "workerQueueScheduledSplitEnabled",
23-
workerQueueV2Enabled: "workerQueueV2Enabled",
2422
workerQueueCompatibility: "workerQueueCompatibility",
2523
workerQueueChannel: "workerQueueChannel",
2624
internalApiOriginEnabled: "internalApiOriginEnabled",
@@ -99,8 +97,6 @@ export const FeatureFlagCatalog = {
9997
// Gates the Interface theme setting in /account. Off by default.
10098
[FEATURE_FLAG.hasThemeSwitcher]: z.coerce.boolean(),
10199
[FEATURE_FLAG.mollifierEnabled]: z.coerce.boolean(),
102-
[FEATURE_FLAG.workerQueueScheduledSplitEnabled]: z.coerce.boolean(),
103-
[FEATURE_FLAG.workerQueueV2Enabled]: z.boolean(),
104100
// Mirrors the core worker-queue enums; defined here because this module is imported client-side.
105101
[FEATURE_FLAG.workerQueueCompatibility]: z.enum(["any", "container", "compute"]),
106102
[FEATURE_FLAG.workerQueueChannel]: z.enum(["stable", "canary"]),
@@ -211,7 +207,6 @@ export const GLOBAL_LOCKED_FLAGS: FeatureFlagKey[] = [
211207
FEATURE_FLAG.runOpsMintShard,
212208
FEATURE_FLAG.runOpsMintShardEnvPins,
213209
FEATURE_FLAG.apiRateLimitMetricsEnabled,
214-
FEATURE_FLAG.workerQueueV2Enabled,
215210
FEATURE_FLAG.workerQueueCompatibility,
216211
FEATURE_FLAG.workerQueueChannel,
217212
// Grace stamps are computed server-side. An editable control here would discard what it saves.

‎apps/webapp/test/engine/triggerTask.test.ts‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ vi.mock("~/services/platform.v3.server", async (importOriginal) => {
1919
};
2020
});
2121

22+
import { env } from "~/env.server";
2223
import { RunEngine } from "@internal/run-engine";
2324
import { setupAuthenticatedEnvironment, setupBackgroundWorker } from "@internal/run-engine/tests";
2425
import { assertNonNullable, containerTest } from "@internal/testcontainers";
@@ -199,6 +200,12 @@ describe("RunEngineTriggerTaskService", () => {
199200
containerTest(
200201
"routes scheduled-lineage runs to a separate worker queue that dequeues independently",
201202
async ({ prisma, redisOptions }) => {
203+
const previousSplitEnabled = env.TRIGGER_WORKER_QUEUE_SCHEDULED_SPLIT_ENABLED;
204+
env.TRIGGER_WORKER_QUEUE_SCHEDULED_SPLIT_ENABLED = "1";
205+
onTestFinished(() => {
206+
env.TRIGGER_WORKER_QUEUE_SCHEDULED_SPLIT_ENABLED = previousSplitEnabled;
207+
});
208+
202209
const engine = new RunEngine({
203210
prisma,
204211
worker: {
@@ -233,12 +240,6 @@ describe("RunEngineTriggerTaskService", () => {
233240
try {
234241
const authenticatedEnvironment = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
235242

236-
// Turn the per-org split flag on in-memory — the resolver reads this
237-
// object directly (no DB round-trip on the trigger hot path).
238-
(authenticatedEnvironment.organization as { featureFlags?: unknown }).featureFlags = {
239-
workerQueueScheduledSplitEnabled: true,
240-
};
241-
242243
const taskIdentifier = "test-task";
243244
await setupBackgroundWorker(engine, authenticatedEnvironment, taskIdentifier);
244245

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { expect, it } from "vitest";
2+
import { FEATURE_FLAG, validatePartialFeatureFlags } from "~/v3/featureFlags";
3+
4+
it("ignores retired worker queue flags without discarding active flags", () => {
5+
const result = validatePartialFeatureFlags({
6+
workerQueueV2Enabled: false,
7+
workerQueueScheduledSplitEnabled: "obsolete",
8+
[FEATURE_FLAG.workerQueueChannel]: "canary",
9+
});
10+
11+
expect(result.success).toBe(true);
12+
if (!result.success) throw result.error;
13+
expect(result.data).toEqual({ [FEATURE_FLAG.workerQueueChannel]: "canary" });
14+
});

0 commit comments

Comments
 (0)