Skip to content

Commit 141590f

Browse files
committed
optional machine preset overrides
1 parent 86cdea9 commit 141590f

File tree

7 files changed

+123
-23
lines changed

7 files changed

+123
-23
lines changed

apps/webapp/app/env.server.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,9 @@ const EnvironmentSchema = z.object({
776776
TRIGGER_BOOTSTRAP_ENABLED: z.string().default("0"),
777777
TRIGGER_BOOTSTRAP_WORKER_GROUP_NAME: z.string().optional(),
778778
TRIGGER_BOOTSTRAP_WORKER_TOKEN_PATH: z.string().optional(),
779+
780+
// Machine presets
781+
MACHINE_PRESETS_OVERRIDE_PATH: z.string().optional(),
779782
});
780783

781784
export type Environment = z.infer<typeof EnvironmentSchema>;

apps/webapp/app/routes/engine.v1.dev.runs.$runFriendlyId.snapshots.$snapshotFriendlyId.attempts.start.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
WorkerApiRunAttemptStartResponseBody,
77
} from "@trigger.dev/core/v3/workers";
88
import { RuntimeEnvironment } from "@trigger.dev/database";
9-
import { defaultMachine } from "@trigger.dev/platform/v3";
9+
import { defaultMachine } from "~/services/platform.v3.server";
1010
import { z } from "zod";
1111
import { prisma } from "~/db.server";
1212
import { generateJWTTokenForEnvironment } from "~/services/apiAuth.server";

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

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { Organization, Project } from "@trigger.dev/database";
1+
import type { Organization, Project } from "@trigger.dev/database";
22
import {
33
BillingClient,
4-
Limits,
5-
SetPlanBody,
6-
UsageSeriesParams,
7-
UsageResult,
4+
type Limits,
5+
type SetPlanBody,
6+
type UsageSeriesParams,
7+
type UsageResult,
8+
defaultMachine as defaultMachineFromPlatform,
9+
machines as machinesFromPlatform,
10+
type MachineCode,
811
} from "@trigger.dev/platform/v3";
912
import { createCache, DefaultStatefulContext, Namespace } from "@unkey/cache";
1013
import { MemoryStore } from "@unkey/cache/stores";
@@ -17,6 +20,9 @@ import { logger } from "~/services/logger.server";
1720
import { newProjectPath, organizationBillingPath } from "~/utils/pathBuilder";
1821
import { singleton } from "~/utils/singleton";
1922
import { RedisCacheStore } from "./unkey/redisCacheStore.server";
23+
import { existsSync, readFileSync } from "node:fs";
24+
import { z } from "zod";
25+
import { MachinePresetName } from "@trigger.dev/core/v3";
2026

2127
function initializeClient() {
2228
if (isCloud() && process.env.BILLING_API_URL && process.env.BILLING_API_KEY) {
@@ -67,6 +73,111 @@ function initializePlatformCache() {
6773

6874
const platformCache = singleton("platformCache", initializePlatformCache);
6975

76+
type Machines = typeof machinesFromPlatform;
77+
78+
const MachineOverrideValues = z.object({
79+
cpu: z.number(),
80+
memory: z.number(),
81+
});
82+
type MachineOverrideValues = z.infer<typeof MachineOverrideValues>;
83+
84+
const MachineOverrides = z.record(MachinePresetName, MachineOverrideValues.partial());
85+
type MachineOverrides = z.infer<typeof MachineOverrides>;
86+
87+
const MachinePresetOverrides = z.object({
88+
defaultMachine: MachinePresetName.optional(),
89+
machines: MachineOverrides.optional(),
90+
});
91+
92+
function initializeMachinePresets(): {
93+
defaultMachine: MachineCode;
94+
machines: Machines;
95+
} {
96+
const overrides = getMachinePresetOverrides();
97+
98+
if (!overrides) {
99+
return {
100+
defaultMachine: defaultMachineFromPlatform,
101+
machines: machinesFromPlatform,
102+
};
103+
}
104+
105+
return {
106+
defaultMachine: overrideDefaultMachine(defaultMachineFromPlatform, overrides.defaultMachine),
107+
machines: overrideMachines(machinesFromPlatform, overrides.machines),
108+
};
109+
}
110+
111+
export const { defaultMachine, machines } = singleton("machinePresets", initializeMachinePresets);
112+
113+
function overrideDefaultMachine(defaultMachine: MachineCode, override?: MachineCode): MachineCode {
114+
if (!override) {
115+
return defaultMachine;
116+
}
117+
118+
return override;
119+
}
120+
121+
function overrideMachines(machines: Machines, overrides?: MachineOverrides): Machines {
122+
if (!overrides) {
123+
return machines;
124+
}
125+
126+
const mergedMachines = {
127+
...machines,
128+
};
129+
130+
for (const machine of Object.keys(overrides) as MachinePresetName[]) {
131+
mergedMachines[machine] = {
132+
...mergedMachines[machine],
133+
...overrides[machine],
134+
};
135+
}
136+
137+
return mergedMachines;
138+
}
139+
140+
function getMachinePresetOverrides() {
141+
const path = env.MACHINE_PRESETS_OVERRIDE_PATH;
142+
if (!path) {
143+
return;
144+
}
145+
146+
const overrides = safeReadMachinePresetOverrides(path);
147+
if (!overrides) {
148+
return;
149+
}
150+
151+
const parsed = MachinePresetOverrides.safeParse(overrides);
152+
153+
if (!parsed.success) {
154+
logger.error("Error parsing machine preset overrides", { path, error: parsed.error });
155+
return;
156+
}
157+
158+
return parsed.data;
159+
}
160+
161+
function safeReadMachinePresetOverrides(path: string) {
162+
try {
163+
const fileExists = existsSync(path);
164+
if (!fileExists) {
165+
logger.error("Machine preset overrides file does not exist", { path });
166+
return;
167+
}
168+
169+
const fileContents = readFileSync(path, "utf8");
170+
171+
return JSON.parse(fileContents);
172+
} catch (error) {
173+
logger.error("Error reading machine preset overrides", {
174+
path,
175+
error: error instanceof Error ? error.message : String(error),
176+
});
177+
return;
178+
}
179+
}
180+
70181
export async function getCurrentPlan(orgId: string) {
71182
if (!client) return undefined;
72183

apps/webapp/app/v3/machinePresets.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { MachineConfig, MachinePreset, MachinePresetName } from "@trigger.dev/core/v3";
2-
import { defaultMachine, machines } from "@trigger.dev/platform/v3";
2+
import { defaultMachine, machines } from "~/services/platform.v3.server";
33
import { logger } from "~/services/logger.server";
44

55
export function machinePresetFromConfig(config: unknown): MachinePreset {

apps/webapp/app/v3/runEngine.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { RunEngine } from "@internal/run-engine";
2-
import { defaultMachine } from "@trigger.dev/platform/v3";
2+
import { defaultMachine } from "~/services/platform.v3.server";
33
import { prisma } from "~/db.server";
44
import { env } from "~/env.server";
55
import { singleton } from "~/utils/singleton";

apps/webapp/app/v3/services/worker/workerGroupTokenService.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
fromFriendlyId,
3030
} from "@trigger.dev/core/v3/isomorphic";
3131
import { machinePresetFromName } from "~/v3/machinePresets.server";
32-
import { defaultMachine } from "@trigger.dev/platform/v3";
32+
import { defaultMachine } from "~/services/platform.v3.server";
3333

3434
export class WorkerGroupTokenService extends WithRunEngine {
3535
private readonly tokenPrefix = "tr_wgt_";

packages/cli-v3/src/utilities/fileSystem.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,6 @@ export async function readJSONFile(path: string) {
5656
return JSON.parse(fileContents);
5757
}
5858

59-
export async function safeFeadJSONFile(path: string) {
60-
try {
61-
const fileExists = await pathExists(path);
62-
63-
if (!fileExists) return;
64-
65-
const fileContents = await readFile(path);
66-
67-
return JSON.parse(fileContents);
68-
} catch {
69-
return;
70-
}
71-
}
72-
7359
export async function writeJSONFile(path: string, json: any, pretty = false) {
7460
await writeFile(path, JSON.stringify(json, undefined, pretty ? 2 : undefined), "utf8");
7561
}

0 commit comments

Comments
 (0)