Skip to content
File

Blob: src/worker/contracts/control.ts

typescript162 lines
1import { eg, type TypeFromCodec } from "@cloudflare/util-en-garde";
2 
3import { CommitSha, ProjectId, RunId, UnixTimestampMs } from "@/contracts/common";
4import { AcceptedRunSnapshot } from "./project-run";
5import { ProjectRunStatus, ProjectRunTerminalStatus } from "./primitives";
6 
7const NullableTimestamp = eg.union([UnixTimestampMs, eg.null]);
8 
9export const ClaimRunWorkInput = eg.exactStrict(
10 eg.object({
11 projectId: ProjectId,
12 runId: RunId,
13 }),
14);
15export type ClaimRunWorkInput = TypeFromCodec<typeof ClaimRunWorkInput>;
16 
17export const ClaimRunWorkStaleReason = eg.union([
18 eg.literal("run_missing"),
19 eg.literal("run_active"),
20 eg.literal("canceled"),
21 eg.literal("superseded"),
22 eg.literal("already_terminal"),
23 eg.literal("not_currently_executable"),
24]);
25export type ClaimRunWorkStaleReason = TypeFromCodec<typeof ClaimRunWorkStaleReason>;
26 
27const ExecuteRunWork = eg.exactStrict(
28 eg.object({
29 kind: eg.literal("execute"),
30 snapshot: AcceptedRunSnapshot,
31 }),
32);
33 
34const StaleRunWork = eg.exactStrict(
35 eg.object({
36 kind: eg.literal("stale"),
37 reason: ClaimRunWorkStaleReason,
38 }),
39);
40 
41export const ClaimRunWorkResult = eg.union([ExecuteRunWork, StaleRunWork]);
42export type ClaimRunWorkResult = TypeFromCodec<typeof ClaimRunWorkResult>;
43export type ExecuteRunWork = Extract<ClaimRunWorkResult, { kind: "execute" }>;
44 
45export const RunControlState = eg.exactStrict(
46 eg.object({
47 runId: RunId,
48 status: ProjectRunStatus,
49 cancelRequestedAt: NullableTimestamp,
50 }),
51);
52export type RunControlState = TypeFromCodec<typeof RunControlState>;
53 
54export const RequestRunCancelInput = eg.exactStrict(
55 eg.object({
56 projectId: ProjectId,
57 runId: RunId,
58 }),
59);
60export type RequestRunCancelInput = TypeFromCodec<typeof RequestRunCancelInput>;
61 
62export const RequestRunCancelResult = RunControlState;
63export type RequestRunCancelResult = TypeFromCodec<typeof RequestRunCancelResult>;
64 
65export const RunHeartbeatInput = eg.exactStrict(
66 eg.object({
67 projectId: ProjectId,
68 runId: RunId,
69 }),
70);
71export type RunHeartbeatInput = TypeFromCodec<typeof RunHeartbeatInput>;
72 
73export const RunHeartbeatResult = eg.union([RunControlState, eg.null]);
74export type RunHeartbeatResult = TypeFromCodec<typeof RunHeartbeatResult>;
75 
76export const RecoverWorkflowDispatchFailureInput = eg.exactStrict(
77 eg.object({
78 projectId: ProjectId,
79 runId: RunId,
80 errorMessage: eg.string,
81 }),
82);
83export type RecoverWorkflowDispatchFailureInput = TypeFromCodec<typeof RecoverWorkflowDispatchFailureInput>;
84 
85const RecoverWorkflowDispatchFailureRearmedResult = eg.exactStrict(
86 eg.object({
87 kind: eg.literal("rearmed"),
88 }),
89);
90 
91const RecoverWorkflowDispatchFailureAlreadyActiveResult = eg.exactStrict(
92 eg.object({
93 kind: eg.literal("already_active"),
94 }),
95);
96 
97const RecoverWorkflowDispatchFailureTerminalResult = eg.exactStrict(
98 eg.object({
99 kind: eg.literal("terminal"),
100 }),
101);
102 
103const RecoverWorkflowDispatchFailureStaleResult = eg.exactStrict(
104 eg.object({
105 kind: eg.literal("stale"),
106 }),
107);
108 
109export const RecoverWorkflowDispatchFailureResult = eg.union([
110 RecoverWorkflowDispatchFailureRearmedResult,
111 RecoverWorkflowDispatchFailureAlreadyActiveResult,
112 RecoverWorkflowDispatchFailureTerminalResult,
113 RecoverWorkflowDispatchFailureStaleResult,
114]);
115export type RecoverWorkflowDispatchFailureResult = TypeFromCodec<typeof RecoverWorkflowDispatchFailureResult>;
116 
117export const FinalizeRunExecutionInput = eg.exactStrict(
118 eg.object({
119 projectId: ProjectId,
120 runId: RunId,
121 terminalStatus: ProjectRunTerminalStatus,
122 lastError: eg.union([eg.string, eg.null]),
123 sandboxDestroyed: eg.boolean,
124 }),
125);
126export type FinalizeRunExecutionInput = TypeFromCodec<typeof FinalizeRunExecutionInput>;
127 
128export const FinalizeRunExecutionResult = eg.exactStrict(
129 eg.object({
130 snapshot: AcceptedRunSnapshot,
131 }),
132);
133export type FinalizeRunExecutionResult = TypeFromCodec<typeof FinalizeRunExecutionResult>;
134 
135export const RecordRunResolvedCommitInput = eg.exactStrict(
136 eg.object({
137 projectId: ProjectId,
138 runId: RunId,
139 commitSha: CommitSha,
140 }),
141);
142export type RecordRunResolvedCommitInput = TypeFromCodec<typeof RecordRunResolvedCommitInput>;
143 
144const RecordRunResolvedCommitAppliedResult = eg.exactStrict(
145 eg.object({
146 kind: eg.literal("applied"),
147 }),
148);
149 
150const RecordRunResolvedCommitStaleResult = eg.exactStrict(
151 eg.object({
152 kind: eg.literal("stale"),
153 status: eg.union([ProjectRunStatus, eg.null]),
154 }),
155);
156 
157export const RecordRunResolvedCommitResult = eg.union([
158 RecordRunResolvedCommitAppliedResult,
159 RecordRunResolvedCommitStaleResult,
160]);
161export type RecordRunResolvedCommitResult = TypeFromCodec<typeof RecordRunResolvedCommitResult>;