Skip to content

Commit 0a0f5b6

Browse files
Merge branch 'main' into issue/ffmpegv7
2 parents f5ec17f + 4fda8a5 commit 0a0f5b6

File tree

26 files changed

+2030
-485
lines changed

26 files changed

+2030
-485
lines changed

.cursor/rules/writing-tasks.mdc

Lines changed: 1270 additions & 0 deletions
Large diffs are not rendered by default.

.dockerignore

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,23 @@
1-
\*.log
2-
.git
3-
.github
4-
5-
# editor
6-
7-
.idea
8-
.vscode
9-
10-
# dependencies
11-
1+
**/*.log
2+
**/*.pem
3+
**/*.tsbuildinfo
4+
5+
**/.cache
6+
**/.env
7+
**/.next
8+
**/.output
9+
**/.trigger
10+
**/.tshy
11+
**/.tshy-build
12+
**/.turbo
13+
**/.vercel
14+
**/.wrangler
15+
16+
**/dist
1217
**/node_modules
13-
.pnp
14-
.pnp.js
15-
16-
# testing
17-
18-
coverage
19-
20-
# next.js
2118

22-
.next/
23-
build
24-
25-
# packages
26-
27-
build
28-
dist
29-
packages/\*\*/dist
30-
31-
# misc
32-
33-
.DS_Store
34-
\*.pem
35-
36-
.turbo
37-
.vercel
38-
.cache
39-
.output
40-
.trigger
41-
apps/\*\*/public/build
19+
apps/webapp/build
20+
apps/webapp/public/build
4221

4322
cypress/screenshots
4423
cypress/videos
@@ -47,8 +26,21 @@ apps/**/styles/tailwind.css
4726
packages/**/styles/tailwind.css
4827

4928
.changeset
50-
references
29+
.DS_Store
30+
.git
31+
.github
32+
.idea
33+
.pnp
34+
.pnp.js
35+
.vscode
36+
37+
coverage
38+
build
39+
docs
5140
examples
41+
out
42+
references
43+
5244
CHANGESETS.md
5345
CONTRIBUTING.md
5446
README.md

.npmrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
link-workspace-packages=false
22
public-hoist-pattern[]=*prisma*
33
prefer-workspace-packages=true
4-
update-notifier=false
4+
update-notifier=false
5+
side-effects-cache=false

apps/supervisor/Containerfile

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ FROM node-22-alpine AS pruner
66

77
COPY --chown=node:node . .
88
RUN npx -q turbo@1.10.9 prune --scope=supervisor --docker
9-
RUN find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
109

1110
FROM node-22-alpine AS base
1211

@@ -17,26 +16,17 @@ COPY --from=pruner --chown=node:node /app/out/json/ .
1716
COPY --from=pruner --chown=node:node /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
1817
COPY --from=pruner --chown=node:node /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
1918

20-
FROM base AS dev-deps
21-
RUN corepack enable
22-
ENV NODE_ENV development
23-
24-
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm fetch --no-frozen-lockfile
25-
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --ignore-scripts --no-frozen-lockfile
26-
27-
FROM base AS prod-deps
28-
RUN corepack enable
29-
ENV NODE_ENV production
19+
RUN corepack enable && corepack prepare --activate
3020

31-
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --prod --no-frozen-lockfile
21+
FROM base AS deps-fetcher
22+
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm fetch --frozen-lockfile
3223

33-
COPY --from=pruner --chown=node:node /app/internal-packages/database/prisma/schema.prisma /app/internal-packages/database/prisma/schema.prisma
24+
FROM deps-fetcher AS dev-deps
25+
ENV NODE_ENV development
3426

35-
ENV NPM_CONFIG_IGNORE_WORKSPACE_ROOT_CHECK true
36-
RUN pnpx prisma@5.4.1 generate --schema /app/internal-packages/database/prisma/schema.prisma
27+
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile --offline --ignore-scripts
3728

3829
FROM base AS builder
39-
RUN corepack enable
4030

4131
COPY --from=pruner --chown=node:node /app/out/full/ .
4232
COPY --from=dev-deps --chown=node:node /app/ .
@@ -45,19 +35,19 @@ COPY --chown=node:node .configs/tsconfig.base.json .configs/tsconfig.base.json
4535
COPY --chown=node:node scripts/updateVersion.ts scripts/updateVersion.ts
4636

4737
RUN pnpm run generate && \
48-
pnpm run -r --filter supervisor... build
38+
pnpm run --filter supervisor... build&& \
39+
pnpm deploy --filter=supervisor --prod /prod/supervisor
4940

5041
FROM base AS runner
5142

52-
RUN corepack enable
5343
ENV NODE_ENV production
5444

55-
COPY --from=pruner --chown=node:node /app/out/full/ .
56-
COPY --from=prod-deps --chown=node:node /app .
57-
COPY --from=builder --chown=node:node /app/apps/supervisor ./apps/supervisor
45+
COPY --from=builder /prod/supervisor /app/apps/supervisor
5846

5947
EXPOSE 8000
60-
6148
USER node
6249

50+
# ensure pnpm is installed during build and not silently downloaded at runtime
51+
RUN pnpm -v
52+
6353
CMD [ "/usr/bin/dumb-init", "--", "pnpm", "run", "--filter", "supervisor", "start"]

apps/supervisor/src/index.ts

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ class ManagedSupervisor {
8787
});
8888

8989
if (env.TRIGGER_CHECKPOINT_URL) {
90+
this.logger.log("[ManagedWorker] 🥶 Checkpoints enabled", {
91+
checkpointUrl: env.TRIGGER_CHECKPOINT_URL,
92+
});
93+
9094
this.checkpointClient = new CheckpointClient({
9195
apiUrl: new URL(env.TRIGGER_CHECKPOINT_URL),
9296
workerClient: this.workerSession.httpClient,
@@ -126,8 +130,13 @@ class ManagedSupervisor {
126130
if (message.checkpoint) {
127131
this.logger.log("[ManagedWorker] Restoring run", { runId: message.run.id });
128132

133+
if (!this.checkpointClient) {
134+
this.logger.error("[ManagedWorker] No checkpoint client", { runId: message.run.id });
135+
return;
136+
}
137+
129138
try {
130-
const didRestore = await this.checkpointClient?.restoreRun({
139+
const didRestore = await this.checkpointClient.restoreRun({
131140
runFriendlyId: message.run.friendlyId,
132141
snapshotFriendlyId: message.snapshot.friendlyId,
133142
checkpoint: message.checkpoint,
@@ -214,33 +223,41 @@ class ManagedSupervisor {
214223

215224
const warmStartUrlWithPath = new URL("/warm-start", this.warmStartUrl);
216225

217-
const res = await fetch(warmStartUrlWithPath.href, {
218-
method: "POST",
219-
headers: {
220-
"Content-Type": "application/json",
221-
},
222-
body: JSON.stringify({ dequeuedMessage }),
223-
});
224-
225-
if (!res.ok) {
226-
this.logger.error("[ManagedWorker] Warm start failed", {
227-
runId: dequeuedMessage.run.id,
226+
try {
227+
const res = await fetch(warmStartUrlWithPath.href, {
228+
method: "POST",
229+
headers: {
230+
"Content-Type": "application/json",
231+
},
232+
body: JSON.stringify({ dequeuedMessage }),
228233
});
229-
return false;
230-
}
231234

232-
const data = await res.json();
233-
const parsedData = z.object({ didWarmStart: z.boolean() }).safeParse(data);
235+
if (!res.ok) {
236+
this.logger.error("[ManagedWorker] Warm start failed", {
237+
runId: dequeuedMessage.run.id,
238+
});
239+
return false;
240+
}
241+
242+
const data = await res.json();
243+
const parsedData = z.object({ didWarmStart: z.boolean() }).safeParse(data);
234244

235-
if (!parsedData.success) {
236-
this.logger.error("[ManagedWorker] Warm start response invalid", {
245+
if (!parsedData.success) {
246+
this.logger.error("[ManagedWorker] Warm start response invalid", {
247+
runId: dequeuedMessage.run.id,
248+
data,
249+
});
250+
return false;
251+
}
252+
253+
return parsedData.data.didWarmStart;
254+
} catch (error) {
255+
this.logger.error("[ManagedWorker] Warm start error", {
237256
runId: dequeuedMessage.run.id,
238-
data,
257+
error,
239258
});
240259
return false;
241260
}
242-
243-
return parsedData.data.didWarmStart;
244261
}
245262

246263
async start() {

apps/supervisor/src/util.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,6 @@
1-
import { customAlphabet } from "nanoid";
2-
31
export function getDockerHostDomain() {
42
const isMacOs = process.platform === "darwin";
53
const isWindows = process.platform === "win32";
64

75
return isMacOs || isWindows ? "host.docker.internal" : "localhost";
86
}
9-
10-
export class IdGenerator {
11-
private alphabet: string;
12-
private length: number;
13-
private prefix: string;
14-
15-
constructor({ alphabet, length, prefix }: { alphabet: string; length: number; prefix: string }) {
16-
this.alphabet = alphabet;
17-
this.length = length;
18-
this.prefix = prefix;
19-
}
20-
21-
generate(): string {
22-
return `${this.prefix}${customAlphabet(this.alphabet, this.length)()}`;
23-
}
24-
}
25-
26-
export const RunnerId = new IdGenerator({
27-
alphabet: "123456789abcdefghijkmnopqrstuvwxyz",
28-
length: 20,
29-
prefix: "runner_",
30-
});

apps/supervisor/src/workloadManager/docker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { SimpleStructuredLogger } from "@trigger.dev/core/v3/utils/structuredLogger";
2+
import { RunnerId } from "@trigger.dev/core/v3/isomorphic";
23
import {
34
type WorkloadManager,
45
type WorkloadManagerCreateOptions,
56
type WorkloadManagerOptions,
67
} from "./types.js";
78
import { x } from "tinyexec";
89
import { env } from "../env.js";
9-
import { getDockerHostDomain, RunnerId } from "../util.js";
10+
import { getDockerHostDomain } from "../util.js";
1011

1112
export class DockerWorkloadManager implements WorkloadManager {
1213
private readonly logger = new SimpleStructuredLogger("docker-workload-provider");

apps/supervisor/src/workloadManager/kubernetes.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
type WorkloadManagerCreateOptions,
55
type WorkloadManagerOptions,
66
} from "./types.js";
7-
import { RunnerId } from "../util.js";
7+
import { RunnerId } from "@trigger.dev/core/v3/isomorphic";
88
import type { EnvironmentType, MachinePreset } from "@trigger.dev/core/v3";
99
import { env } from "../env.js";
1010
import { type K8sApi, createK8sApi, type k8s } from "../clients/kubernetes.js";
@@ -48,15 +48,14 @@ export class KubernetesWorkloadManager implements WorkloadManager {
4848
app: "task-run",
4949
"app.kubernetes.io/part-of": "trigger-worker",
5050
"app.kubernetes.io/component": "create",
51-
run: opts.runId,
5251
},
5352
},
5453
spec: {
5554
...this.#defaultPodSpec,
5655
terminationGracePeriodSeconds: 60 * 60,
5756
containers: [
5857
{
59-
name: runnerId,
58+
name: "run-controller",
6059
image: opts.image,
6160
ports: [
6261
{

apps/supervisor/src/workloadServer/index.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -200,30 +200,29 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
200200
handler: async ({ reply, params, req }) => {
201201
console.debug("Suspend request", { params, headers: req.headers });
202202

203-
const runnerId = this.runnerIdFromRequest(req);
204-
205-
if (!runnerId) {
206-
console.error("Invalid headers for suspend request", {
207-
...params,
208-
headers: req.headers,
209-
});
203+
if (!this.checkpointClient) {
210204
reply.json(
211205
{
212206
ok: false,
213-
error: "Invalid headers",
207+
error: "Checkpoints disabled",
214208
} satisfies WorkloadSuspendRunResponseBody,
215209
false,
216210
400
217211
);
218212
return;
219213
}
220214

221-
if (!this.checkpointClient) {
222-
console.error("Checkpoint client unavailable - suspending impossible", { params });
215+
const runnerId = this.runnerIdFromRequest(req);
216+
217+
if (!runnerId) {
218+
console.error("Invalid headers for suspend request", {
219+
...params,
220+
headers: req.headers,
221+
});
223222
reply.json(
224223
{
225224
ok: false,
226-
error: "Suspends are not enabled",
225+
error: "Invalid headers",
227226
} satisfies WorkloadSuspendRunResponseBody,
228227
false,
229228
400

docker/Dockerfile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
FROM node:20.11.1-bullseye-slim@sha256:5a5a92b3a8d392691c983719dbdc65d9f30085d6dcd65376e7a32e6fe9bf4cbe AS pruner
1+
ARG NODE_IMAGE=node:20.11.1-bullseye-slim@sha256:5a5a92b3a8d392691c983719dbdc65d9f30085d6dcd65376e7a32e6fe9bf4cbe
2+
3+
FROM ${NODE_IMAGE} AS pruner
24

35
WORKDIR /triggerdotdev
46

@@ -7,7 +9,7 @@ RUN npx -q turbo@1.10.9 prune --scope=webapp --docker
79
RUN find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
810

911
# Base strategy to have layer caching
10-
FROM node:20.11.1-bullseye-slim@sha256:5a5a92b3a8d392691c983719dbdc65d9f30085d6dcd65376e7a32e6fe9bf4cbe AS base
12+
FROM ${NODE_IMAGE} AS base
1113
RUN apt-get update && apt-get install -y openssl dumb-init
1214
WORKDIR /triggerdotdev
1315
COPY --chown=node:node .gitignore .gitignore
@@ -53,7 +55,7 @@ RUN pnpm run generate
5355
RUN pnpm run build --filter=webapp...
5456

5557
# Runner
56-
FROM node:20.11.1-bullseye-slim@sha256:5a5a92b3a8d392691c983719dbdc65d9f30085d6dcd65376e7a32e6fe9bf4cbe AS runner
58+
FROM ${NODE_IMAGE} AS runner
5759
RUN apt-get update && apt-get install -y openssl netcat-openbsd ca-certificates
5860
WORKDIR /triggerdotdev
5961
RUN corepack enable

0 commit comments

Comments
 (0)