Skip to content

Commit 66c0c5b

Browse files
committed
rework suspend completion
1 parent ecb9cad commit 66c0c5b

File tree

5 files changed

+47
-34
lines changed

5 files changed

+47
-34
lines changed

apps/supervisor/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "module",
77
"scripts": {
88
"build": "tsc",
9-
"dev": "tsx --experimental-sqlite --require dotenv/config --watch src/index.ts",
9+
"dev": "tsx --experimental-sqlite --require dotenv/config --watch src/index.ts || (echo '!! Remember to run: nvm use'; exit 1)",
1010
"start": "node --experimental-sqlite dist/index.js",
1111
"typecheck": "tsc --noEmit"
1212
},

apps/supervisor/src/workloadServer/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,6 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
249249
console.error("Failed to suspend run", { params });
250250
return;
251251
}
252-
253-
console.log("Suspended run", { params });
254252
},
255253
}
256254
)

packages/core/src/v3/runEngineWorker/supervisor/http.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
WorkerApiRunHeartbeatResponseBody,
1616
WorkerApiRunLatestSnapshotResponseBody,
1717
WorkerApiDebugLogBody,
18+
WorkerApiSuspendRunRequestBody,
19+
WorkerApiSuspendRunResponseBody,
1820
} from "./schemas.js";
1921
import { SupervisorClientCommonOptions } from "./types.js";
2022
import { getDefaultWorkerHeaders } from "./util.js";
@@ -220,14 +222,30 @@ export class SupervisorHttpClient {
220222
);
221223
}
222224

223-
getSuspendCompletionUrl(runId: string, snapshotId: string, runnerId?: string) {
224-
return {
225-
url: `${this.apiUrl}/engine/v1/worker-actions/runs/${runId}/snapshots/${snapshotId}/suspend`,
226-
headers: {
227-
...this.defaultHeaders,
228-
...this.runnerIdHeader(runnerId),
229-
},
230-
};
225+
async submitSuspendCompletion({
226+
runId,
227+
snapshotId,
228+
runnerId,
229+
body,
230+
}: {
231+
runId: string;
232+
snapshotId: string;
233+
runnerId?: string;
234+
body: WorkerApiSuspendRunRequestBody;
235+
}) {
236+
return wrapZodFetch(
237+
WorkerApiSuspendRunResponseBody,
238+
`${this.apiUrl}/engine/v1/worker-actions/runs/${runId}/snapshots/${snapshotId}/suspend`,
239+
{
240+
method: "POST",
241+
headers: {
242+
...this.defaultHeaders,
243+
...this.runnerIdHeader(runnerId),
244+
"Content-Type": "application/json",
245+
},
246+
body: JSON.stringify(body),
247+
}
248+
);
231249
}
232250

233251
private runnerIdHeader(runnerId?: string): Record<string, string> {

packages/core/src/v3/runEngineWorker/supervisor/schemas.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,11 @@ export const WorkerApiDebugLogBody = z.object({
142142
properties: Attributes.optional(),
143143
});
144144
export type WorkerApiDebugLogBody = z.infer<typeof WorkerApiDebugLogBody>;
145+
146+
export const WorkerApiSuspendCompletionResponseBody = z.object({
147+
success: z.boolean(),
148+
error: z.string().optional(),
149+
});
150+
export type WorkerApiSuspendCompletionResponseBody = z.infer<
151+
typeof WorkerApiSuspendCompletionResponseBody
152+
>;

packages/core/src/v3/serverOnly/checkpointClient.ts

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ export class CheckpointClient {
2121
return new URL("/api/v1/restore", this.apiUrl);
2222
}
2323

24-
private get suspendUrl() {
25-
return new URL("/api/v1/suspend", this.apiUrl);
26-
}
27-
2824
constructor(opts: CheckpointClientOptions) {
2925
this.apiUrl = opts.apiUrl;
3026
this.workerClient = opts.workerClient;
@@ -41,26 +37,19 @@ export class CheckpointClient {
4137
containerId: string;
4238
runnerId: string;
4339
}): Promise<boolean> {
44-
const completionUrl = this.workerClient.getSuspendCompletionUrl(
45-
runFriendlyId,
46-
snapshotFriendlyId,
47-
runnerId
48-
);
49-
50-
const res = await fetch(this.suspendUrl, {
51-
method: "POST",
52-
headers: {
53-
"Content-Type": "application/json",
54-
},
55-
body: JSON.stringify({
56-
type: "DOCKER",
57-
containerId,
58-
callbacks: {
59-
completion: completionUrl.url,
60-
headers: completionUrl.headers,
40+
const res = await fetch(
41+
new URL(`/api/v1/runs/${runFriendlyId}/snapshots/${snapshotFriendlyId}/suspend`, this.apiUrl),
42+
{
43+
method: "POST",
44+
headers: {
45+
"Content-Type": "application/json",
6146
},
62-
} satisfies CheckpointServiceSuspendRequestBodyInput),
63-
});
47+
body: JSON.stringify({
48+
type: "DOCKER",
49+
containerId,
50+
} satisfies CheckpointServiceSuspendRequestBodyInput),
51+
}
52+
);
6453

6554
if (!res.ok) {
6655
this.logger.error("[CheckpointClient] Suspend request failed", {

0 commit comments

Comments
 (0)