Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/resources/devboxes/devboxes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ export class Devboxes extends APIResource {
/**
* Wait for a devbox to reach the running state.
* Polls the devbox status until it reaches running state or fails with an error.
*
* @param id - Devbox ID
* @param options - request options to specify retries, timeout, polling, etc.
*/
async awaitRunning(
id: string,
Expand All @@ -168,7 +171,6 @@ export class Devboxes extends APIResource {
// Otherwise it throws an 408 error when times out.
return this._client.post(`/v1/devboxes/${id}/wait_for_status`, {
body: { statuses: ['running', 'failure'] },
...options,
});
};

Expand Down Expand Up @@ -202,6 +204,9 @@ export class Devboxes extends APIResource {
/**
* Create a devbox and wait for it to reach the running state.
* This is a convenience method that combines create() and awaitDevboxRunning().
*
* @param body - DevboxCreateParams
* @param options - request options to specify retries, timeout, polling, etc.
*/
async createAndAwaitRunning(
body?: DevboxCreateParams,
Expand Down
25 changes: 23 additions & 2 deletions src/resources/devboxes/executions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export class Executions extends APIResource {
/**
* Wait for an async execution to complete.
* Polls the execution status until it reaches completed state.
*
* @param id - Devbox ID
* @param executionId - Execution ID
* @param options - request options to specify retries, timeout, polling, etc.
*/
async awaitCompleted(
id: string,
Expand All @@ -57,14 +61,31 @@ export class Executions extends APIResource {
polling?: Partial<PollingOptions<DevboxesAPI.DevboxAsyncExecutionDetailView>>;
},
): Promise<DevboxesAPI.DevboxAsyncExecutionDetailView> {
const longPoll = (): Promise<DevboxesAPI.DevboxAsyncExecutionDetailView> => {
// This either returns a DevboxAsyncExecutionDetailView when execution status is completed;
// Otherwise it throws an 408 error when times out.
return this._client.post(`/v1/devboxes/${id}/executions/${executionId}/wait_for_status`, {
body: { statuses: ['completed'] },
});
};

const finalResult = await poll(
() => this.retrieve(id, executionId, options),
() => this.retrieve(id, executionId, options),
() => longPoll(),
() => longPoll(),
{
...options?.polling,
shouldStop: (result: DevboxesAPI.DevboxAsyncExecutionDetailView) => {
return result.status === 'completed';
},
onError: (error) => {
if (error.status === 408) {
// Return a placeholder result to continue polling
return { status: 'running' } as DevboxesAPI.DevboxAsyncExecutionDetailView;
}

// For any other error, rethrow it
throw error;
},
},
);

Expand Down