Skip to content

Commit 38273ae

Browse files
committed
branded type for resolver ids
1 parent e72bcc8 commit 38273ae

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

packages/core/src/v3/runtime/sharedRuntimeManager.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ import { ExecutorToWorkerProcessConnection } from "../zodIpc.js";
1414
import { RuntimeManager } from "./manager.js";
1515
import { preventMultipleWaits } from "./preventMultipleWaits.js";
1616

17+
/** A function that resolves a waitpoint */
1718
type Resolver = (value: CompletedWaitpoint) => void;
1819

20+
/** Branded type for resolver IDs to keep us from doing anything stupid */
21+
type ResolverId = string & { readonly __brand: unique symbol };
22+
1923
export class SharedRuntimeManager implements RuntimeManager {
2024
/** Maps a resolver ID to a resolver function */
21-
private readonly resolversById = new Map<string, Resolver>();
25+
private readonly resolversById = new Map<ResolverId, Resolver>();
2226

2327
/** Stores waitpoints that arrive before their resolvers have been created */
24-
private readonly waitpointsByResolverId = new Map<string, CompletedWaitpoint>();
28+
private readonly waitpointsByResolverId = new Map<ResolverId, CompletedWaitpoint>();
2529

2630
private _preventMultipleWaits = preventMultipleWaits();
2731

@@ -42,7 +46,7 @@ export class SharedRuntimeManager implements RuntimeManager {
4246
async waitForTask(params: { id: string; ctx: TaskRunContext }): Promise<TaskRunExecutionResult> {
4347
return this._preventMultipleWaits(async () => {
4448
const promise = new Promise<CompletedWaitpoint>((resolve) => {
45-
this.resolversById.set(params.id, resolve);
49+
this.resolversById.set(params.id as ResolverId, resolve);
4650
});
4751

4852
// Resolve any waitpoints we received before the resolver was created
@@ -76,7 +80,7 @@ export class SharedRuntimeManager implements RuntimeManager {
7680
}
7781

7882
const promises = Array.from({ length: params.runCount }, (_, index) => {
79-
const resolverId = `${params.id}_${index}`;
83+
const resolverId = `${params.id}_${index}` as ResolverId;
8084

8185
return new Promise<CompletedWaitpoint>((resolve, reject) => {
8286
this.resolversById.set(resolverId, resolve);
@@ -116,7 +120,7 @@ export class SharedRuntimeManager implements RuntimeManager {
116120
}): Promise<WaitpointTokenResult> {
117121
return this._preventMultipleWaits(async () => {
118122
const promise = new Promise<CompletedWaitpoint>((resolve) => {
119-
this.resolversById.set(waitpointFriendlyId, resolve);
123+
this.resolversById.set(waitpointFriendlyId as ResolverId, resolve);
120124
});
121125

122126
// Resolve any waitpoints we received before the resolver was created
@@ -160,7 +164,9 @@ export class SharedRuntimeManager implements RuntimeManager {
160164
await Promise.all(waitpoints.map((waitpoint) => this.resolveWaitpoint(waitpoint)));
161165
}
162166

163-
private resolverIdFromWaitpoint(waitpoint: CompletedWaitpoint): string | null {
167+
private resolverIdFromWaitpoint(waitpoint: CompletedWaitpoint): ResolverId | null {
168+
let id: string;
169+
164170
switch (waitpoint.type) {
165171
case "RUN": {
166172
if (!waitpoint.completedByTaskRun) {
@@ -170,31 +176,37 @@ export class SharedRuntimeManager implements RuntimeManager {
170176

171177
if (waitpoint.completedByTaskRun.batch) {
172178
// This run is part of a batch
173-
return `${waitpoint.completedByTaskRun.batch.friendlyId}_${waitpoint.index}`;
179+
id = `${waitpoint.completedByTaskRun.batch.friendlyId}_${waitpoint.index}`;
174180
} else {
175181
// This run is NOT part of a batch
176-
return waitpoint.completedByTaskRun.friendlyId;
182+
id = waitpoint.completedByTaskRun.friendlyId;
177183
}
184+
185+
break;
178186
}
179187
case "BATCH": {
180188
if (!waitpoint.completedByBatch) {
181189
this.log("No completedByBatch for BATCH waitpoint", waitpoint);
182190
return null;
183191
}
184192

185-
return waitpoint.completedByBatch.friendlyId;
193+
id = waitpoint.completedByBatch.friendlyId;
194+
break;
186195
}
187196
case "MANUAL":
188197
case "DATETIME": {
189-
return waitpoint.friendlyId;
198+
id = waitpoint.friendlyId;
199+
break;
190200
}
191201
default: {
192202
assertExhaustive(waitpoint.type);
193203
}
194204
}
205+
206+
return id as ResolverId;
195207
}
196208

197-
private resolveWaitpoint(waitpoint: CompletedWaitpoint, resolverId?: string | null): void {
209+
private resolveWaitpoint(waitpoint: CompletedWaitpoint, resolverId?: ResolverId | null): void {
198210
this.log("resolveWaitpoint", waitpoint);
199211

200212
if (waitpoint.type === "BATCH") {

0 commit comments

Comments
 (0)