Skip to content

Commit d8d6f4c

Browse files
committed
fix(devbox): reconcile onEvict with generated stream and 2-arg callback
- Use the real generated event type DevboxEvictionEventView (the endpoint's view) in place of the assumed DevboxEvictionEvent. - Invoke the callback as callback(devbox, evictionDeadlineMs): the Devbox object and the Unix millisecond deadline, instead of passing the raw event. Requires the main-repo stainless config change that generates watchEvictions as Stream<DevboxEvictionEventView> (runloopai/runloop#10404). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent f675191 commit d8d6f4c

2 files changed

Lines changed: 28 additions & 27 deletions

File tree

src/sdk/devbox.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,20 +1036,21 @@ export class Devbox {
10361036
*
10371037
* The first `onEvict` across any devbox on this client opens a single account-wide
10381038
* notification stream; it closes automatically once every registered devbox has been
1039-
* notified. The callback runs at most once and receives the eviction event (with its
1040-
* `eviction_deadline_ms`) — use it to run cleanup before the devbox is suspended.
1039+
* notified. The callback runs at most once and is invoked as
1040+
* `callback(devbox, evictionDeadlineMs)` — this devbox and the Unix millisecond
1041+
* deadline by which it will be suspended. Use it to run cleanup before suspend.
10411042
*
1042-
* @param {EvictionCallback} callback - Invoked with the eviction event for this devbox.
1043+
* @param {EvictionCallback} callback - Invoked with this devbox and its eviction deadline (ms).
10431044
*
10441045
* @example
10451046
* ```typescript
1046-
* devbox.onEvict((event) => {
1047-
* console.log(`devbox will be suspended at ${event.eviction_deadline_ms}`);
1047+
* devbox.onEvict((devbox, evictionDeadlineMs) => {
1048+
* console.log(`${devbox.id} will be suspended at ${evictionDeadlineMs}`);
10481049
* });
10491050
* ```
10501051
*/
10511052
onEvict(callback: EvictionCallback): void {
1052-
getEvictionMonitor(this.client).register(this._id, callback);
1053+
getEvictionMonitor(this.client).register(this, callback);
10531054
}
10541055

10551056
/**

src/sdk/eviction.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { Runloop } from '../index';
22
import { Stream } from '../streaming';
3-
// Assumed Stainless-generated SSE event type for `watchEvictions`; carries
4-
// `devbox_id` and `eviction_deadline_ms`. Reconcile the import once the generated
5-
// code lands.
6-
import type { DevboxEvictionEvent } from '../resources/devboxes/devboxes';
3+
import type { DevboxEvictionEventView } from '../resources/devboxes/devboxes';
4+
import type { Devbox } from './devbox';
75

86
/**
9-
* Invoked once with the eviction event for the devbox it was registered for.
10-
* The event carries `devbox_id` and `eviction_deadline_ms`.
7+
* Invoked once when the devbox it was registered for has a pending eviction.
8+
*
9+
* @param devbox - The devbox with a pending eviction.
10+
* @param evictionDeadlineMs - Unix timestamp (ms) by which the devbox will be suspended.
1111
*/
12-
export type EvictionCallback = (event: DevboxEvictionEvent) => void;
12+
export type EvictionCallback = (devbox: Devbox, evictionDeadlineMs: number) => void;
1313

1414
/**
1515
* Fans account-wide eviction notifications out to per-devbox callbacks.
@@ -28,15 +28,15 @@ export type EvictionCallback = (event: DevboxEvictionEvent) => void;
2828
* callback fires at most once even if the server repeats the notification.
2929
*/
3030
export class EvictionMonitor {
31-
private callbacks = new Map<string, EvictionCallback>();
32-
private stream: Stream<DevboxEvictionEvent> | null = null;
31+
private entries = new Map<string, { devbox: Devbox; callback: EvictionCallback }>();
32+
private stream: Stream<DevboxEvictionEventView> | null = null;
3333
private running = false;
3434

3535
constructor(private client: Runloop) {}
3636

37-
/** Add `devboxId` to the interest set, opening the stream if idle. */
38-
register(devboxId: string, callback: EvictionCallback): void {
39-
this.callbacks.set(devboxId, callback);
37+
/** Add `devbox` to the interest set, opening the stream if idle. */
38+
register(devbox: Devbox, callback: EvictionCallback): void {
39+
this.entries.set(devbox.id, { devbox, callback });
4040
if (!this.running) {
4141
this.running = true;
4242
void this.run();
@@ -45,15 +45,15 @@ export class EvictionMonitor {
4545

4646
/** Drop `devboxId`; close the stream if it was the last interested devbox. */
4747
unregister(devboxId: string): void {
48-
this.callbacks.delete(devboxId);
49-
if (this.callbacks.size === 0) {
48+
this.entries.delete(devboxId);
49+
if (this.entries.size === 0) {
5050
this.close();
5151
}
5252
}
5353

5454
/** Clear all interest and tear down the stream. */
5555
close(): void {
56-
this.callbacks.clear();
56+
this.entries.clear();
5757
this.stream?.controller.abort();
5858
this.stream = null;
5959
this.running = false;
@@ -65,7 +65,7 @@ export class EvictionMonitor {
6565
this.stream = stream;
6666
for await (const event of stream) {
6767
this.dispatch(event);
68-
if (this.callbacks.size === 0) break;
68+
if (this.entries.size === 0) break;
6969
}
7070
} catch (error) {
7171
// Aborting the stream on close surfaces as an AbortError; that is expected.
@@ -78,14 +78,14 @@ export class EvictionMonitor {
7878
}
7979
}
8080

81-
private dispatch(event: DevboxEvictionEvent): void {
82-
const callback = this.callbacks.get(event.devbox_id);
83-
if (!callback) return;
81+
private dispatch(event: DevboxEvictionEventView): void {
82+
const entry = this.entries.get(event.devbox_id);
83+
if (!entry) return;
8484
// Remove before signaling so a duplicate notification for the same devbox is
8585
// discarded and the callback fires at most once.
86-
this.callbacks.delete(event.devbox_id);
86+
this.entries.delete(event.devbox_id);
8787
try {
88-
callback(event);
88+
entry.callback(entry.devbox, event.eviction_deadline_ms);
8989
} catch (error) {
9090
console.error(`Error in eviction callback for devbox ${event.devbox_id}:`, error);
9191
}

0 commit comments

Comments
 (0)