Skip to content

Commit d0149e9

Browse files
committed
feat(webapp): add compute template creation service
1 parent 441334b commit d0149e9

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

apps/webapp/app/env.server.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,11 @@ const EnvironmentSchema = z
333333
.optional()
334334
.transform((v) => v ?? process.env.DEPLOY_REGISTRY_ECR_ASSUME_ROLE_EXTERNAL_ID),
335335

336+
// Compute gateway (template creation during deploy finalize)
337+
COMPUTE_GATEWAY_URL: z.string().optional(),
338+
COMPUTE_GATEWAY_AUTH_TOKEN: z.string().optional(),
339+
COMPUTE_TEMPLATE_SHADOW_ROLLOUT_PCT: z.string().optional(),
340+
336341
DEPLOY_IMAGE_PLATFORM: z.string().default("linux/amd64"),
337342
DEPLOY_TIMEOUT_MS: z.coerce
338343
.number()
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { ComputeGatewayClient } from "@trigger.dev/core/v3/compute";
2+
import { env } from "~/env.server";
3+
import { logger } from "~/services/logger.server";
4+
import type { PrismaClientOrTransaction } from "~/db.server";
5+
6+
type TemplateCreationMode = "required" | "shadow" | "skip";
7+
8+
export class ComputeTemplateCreationService {
9+
private client: ComputeGatewayClient | undefined;
10+
11+
constructor() {
12+
if (env.COMPUTE_GATEWAY_URL) {
13+
this.client = new ComputeGatewayClient({
14+
gatewayUrl: env.COMPUTE_GATEWAY_URL,
15+
authToken: env.COMPUTE_GATEWAY_AUTH_TOKEN,
16+
timeoutMs: 5 * 60 * 1000, // 5 minutes
17+
});
18+
}
19+
}
20+
21+
async resolveMode(
22+
projectId: string,
23+
prisma: PrismaClientOrTransaction
24+
): Promise<TemplateCreationMode> {
25+
const project = await prisma.project.findFirst({
26+
where: { id: projectId },
27+
select: {
28+
defaultWorkerGroup: {
29+
select: { workloadType: true },
30+
},
31+
},
32+
});
33+
34+
if (project?.defaultWorkerGroup?.workloadType === "MICROVM") {
35+
return "required";
36+
}
37+
38+
// TODO: check private beta feature flag for org
39+
40+
const rolloutPct = Number(env.COMPUTE_TEMPLATE_SHADOW_ROLLOUT_PCT ?? "0");
41+
if (rolloutPct > 0 && Math.random() * 100 < rolloutPct) {
42+
return "shadow";
43+
}
44+
45+
return "skip";
46+
}
47+
48+
async createTemplate(imageReference: string): Promise<{ success: boolean; error?: string }> {
49+
if (!this.client) {
50+
return { success: false, error: "Compute gateway not configured" };
51+
}
52+
53+
try {
54+
await this.client.createTemplate({
55+
image: imageReference,
56+
cpu: 0.5,
57+
memory_mb: 512,
58+
});
59+
return { success: true };
60+
} catch (error) {
61+
const message = error instanceof Error ? error.message : "Unknown error";
62+
logger.error("Failed to create compute template", {
63+
imageReference,
64+
error: message,
65+
});
66+
return { success: false, error: message };
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)