@skrr-ai/cli 0.1.30 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -63,3 +63,5 @@ export declare abstract class DedicatedLeaseCommand extends BaseCommand {
|
|
|
63
63
|
workspace?: string;
|
|
64
64
|
}, goal: DedicatedWaitGoal | null, verb: string): Promise<void>;
|
|
65
65
|
}
|
|
66
|
+
/** The same transient verdict BaseCommand gives an ordinary API call. */
|
|
67
|
+
export declare function dedicatedRuntimeApiErrorRetryable(err: unknown): boolean;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DedicatedLeaseCommand = exports.DEDICATED_LEASE_ARG_DESCRIPTION = exports.DEDICATED_SELF_LEASE = exports.dedicatedWaitFlags = void 0;
|
|
4
|
+
exports.dedicatedRuntimeApiErrorRetryable = dedicatedRuntimeApiErrorRetryable;
|
|
4
5
|
const core_1 = require("@oclif/core");
|
|
5
6
|
const base_command_1 = require("../base-command");
|
|
7
|
+
const api_fetch_1 = require("./api-fetch");
|
|
6
8
|
const dedicated_machines_1 = require("./dedicated-machines");
|
|
7
9
|
const dedicated_terminal_1 = require("./dedicated-terminal");
|
|
8
10
|
const daemonBroker_1 = require("./daemonBroker");
|
|
@@ -129,8 +131,9 @@ class DedicatedLeaseCommand extends base_command_1.BaseCommand {
|
|
|
129
131
|
this.failWithCliError({
|
|
130
132
|
message,
|
|
131
133
|
code: (0, dedicated_machines_1.dedicatedRuntimeApiErrorCode)(err) ?? 'CLI_ERROR',
|
|
134
|
+
status: err instanceof api_fetch_1.ApiFetchError ? err.status : undefined,
|
|
132
135
|
exit: 1,
|
|
133
|
-
retryable:
|
|
136
|
+
retryable: dedicatedRuntimeApiErrorRetryable(err),
|
|
134
137
|
details: (0, dedicated_machines_1.dedicatedRuntimeApiErrorDetails)(err),
|
|
135
138
|
});
|
|
136
139
|
}
|
|
@@ -176,8 +179,23 @@ class DedicatedLeaseCommand extends base_command_1.BaseCommand {
|
|
|
176
179
|
this.error(err.message, { exit: 1 });
|
|
177
180
|
}
|
|
178
181
|
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
179
|
-
if (message)
|
|
180
|
-
|
|
182
|
+
if (message) {
|
|
183
|
+
const retryable = dedicatedRuntimeApiErrorRetryable(err);
|
|
184
|
+
this.failWithCliError({
|
|
185
|
+
message: retryable
|
|
186
|
+
? `Stopped waiting for ${id}; nothing was cancelled and the operation continues server-side. Check it with \`${this.config.bin} machines dedicated show ${id}\`. The status poll failed: ${message}`
|
|
187
|
+
: message,
|
|
188
|
+
code: (0, dedicated_machines_1.dedicatedRuntimeApiErrorCode)(err) ?? 'CLI_ERROR',
|
|
189
|
+
status: err instanceof api_fetch_1.ApiFetchError ? err.status : undefined,
|
|
190
|
+
exit: 1,
|
|
191
|
+
retryable,
|
|
192
|
+
details: {
|
|
193
|
+
...(0, dedicated_machines_1.dedicatedRuntimeApiErrorDetails)(err),
|
|
194
|
+
leaseId: id,
|
|
195
|
+
operationContinues: true,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
}
|
|
181
199
|
this.handleApiError(err);
|
|
182
200
|
}
|
|
183
201
|
}
|
|
@@ -192,3 +210,19 @@ class DedicatedLeaseCommand extends base_command_1.BaseCommand {
|
|
|
192
210
|
}
|
|
193
211
|
}
|
|
194
212
|
exports.DedicatedLeaseCommand = DedicatedLeaseCommand;
|
|
213
|
+
/** The same transient verdict BaseCommand gives an ordinary API call. */
|
|
214
|
+
function dedicatedRuntimeApiErrorRetryable(err) {
|
|
215
|
+
if (!(err instanceof api_fetch_1.ApiFetchError))
|
|
216
|
+
return false;
|
|
217
|
+
let body = null;
|
|
218
|
+
try {
|
|
219
|
+
const parsed = JSON.parse(err.body || '');
|
|
220
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
221
|
+
body = parsed;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// The HTTP status remains authoritative for an unparseable edge response.
|
|
226
|
+
}
|
|
227
|
+
return (0, base_command_1.isRetryableFailure)(err.status, body);
|
|
228
|
+
}
|
|
@@ -71,6 +71,7 @@ export declare const DEDICATED_WAIT_TIMEOUT_EXIT = 124;
|
|
|
71
71
|
export declare const DEDICATED_WAIT_DEFAULT_TIMEOUT_MS: number;
|
|
72
72
|
export declare const DEDICATED_WAIT_DEFAULT_INTERVAL_MS: number;
|
|
73
73
|
export declare const DEDICATED_WAIT_MAX_READ_FAILURES = 3;
|
|
74
|
+
export declare const DEDICATED_WAIT_MAX_RATE_LIMIT_FAILURES = 6;
|
|
74
75
|
export declare function waitForDedicatedLease(leaseId: string, goal: DedicatedWaitGoal, options?: DedicatedRuntimeScope & {
|
|
75
76
|
initial?: DedicatedLease;
|
|
76
77
|
intervalMs?: number;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEDICATED_WAIT_MAX_READ_FAILURES = exports.DEDICATED_WAIT_DEFAULT_INTERVAL_MS = exports.DEDICATED_WAIT_DEFAULT_TIMEOUT_MS = exports.DEDICATED_WAIT_TIMEOUT_EXIT = exports.DedicatedWaitFailedError = exports.DedicatedWaitTimeoutError = void 0;
|
|
3
|
+
exports.DEDICATED_WAIT_MAX_RATE_LIMIT_FAILURES = exports.DEDICATED_WAIT_MAX_READ_FAILURES = exports.DEDICATED_WAIT_DEFAULT_INTERVAL_MS = exports.DEDICATED_WAIT_DEFAULT_TIMEOUT_MS = exports.DEDICATED_WAIT_TIMEOUT_EXIT = exports.DedicatedWaitFailedError = exports.DedicatedWaitTimeoutError = void 0;
|
|
4
4
|
exports.evaluateDedicatedWait = evaluateDedicatedWait;
|
|
5
5
|
exports.waitForDedicatedLease = waitForDedicatedLease;
|
|
6
6
|
const dedicated_machines_1 = require("./dedicated-machines");
|
|
7
|
+
const api_fetch_1 = require("./api-fetch");
|
|
7
8
|
const RUNNING_STATES = new Set(['ready', 'active', 'idle']);
|
|
8
9
|
/** Terminal for the lease itself, so no goal but `destroyed` can still be reached. */
|
|
9
10
|
const DEAD_STATES = new Set(['failed', 'lost', 'terminated']);
|
|
@@ -194,6 +195,15 @@ exports.DEDICATED_WAIT_TIMEOUT_EXIT = 124;
|
|
|
194
195
|
exports.DEDICATED_WAIT_DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;
|
|
195
196
|
exports.DEDICATED_WAIT_DEFAULT_INTERVAL_MS = 5 * 1000;
|
|
196
197
|
exports.DEDICATED_WAIT_MAX_READ_FAILURES = 3;
|
|
198
|
+
exports.DEDICATED_WAIT_MAX_RATE_LIMIT_FAILURES = 6;
|
|
199
|
+
function readRetryDelayMs(err, consecutiveFailures, intervalMs) {
|
|
200
|
+
if (!(err instanceof api_fetch_1.ApiFetchError) || err.status !== 429)
|
|
201
|
+
return intervalMs;
|
|
202
|
+
// A normal five-second poll repeated three times stays inside the same
|
|
203
|
+
// minute bucket and turns a healthy server-side operation into a CLI error.
|
|
204
|
+
// Back off across the bucket boundary while keeping the overall wait bounded.
|
|
205
|
+
return Math.min(intervalMs * 2 ** consecutiveFailures, 60_000);
|
|
206
|
+
}
|
|
197
207
|
async function waitForDedicatedLease(leaseId, goal, options = {}) {
|
|
198
208
|
const intervalMs = options.intervalMs ?? exports.DEDICATED_WAIT_DEFAULT_INTERVAL_MS;
|
|
199
209
|
const timeoutMs = options.timeoutMs ?? exports.DEDICATED_WAIT_DEFAULT_TIMEOUT_MS;
|
|
@@ -217,9 +227,12 @@ async function waitForDedicatedLease(leaseId, goal, options = {}) {
|
|
|
217
227
|
}
|
|
218
228
|
catch (err) {
|
|
219
229
|
consecutiveReadFailures += 1;
|
|
220
|
-
|
|
230
|
+
const maxFailures = err instanceof api_fetch_1.ApiFetchError && err.status === 429
|
|
231
|
+
? exports.DEDICATED_WAIT_MAX_RATE_LIMIT_FAILURES
|
|
232
|
+
: exports.DEDICATED_WAIT_MAX_READ_FAILURES;
|
|
233
|
+
if (consecutiveReadFailures >= maxFailures)
|
|
221
234
|
throw err;
|
|
222
|
-
await sleep(intervalMs);
|
|
235
|
+
await sleep(readRetryDelayMs(err, consecutiveReadFailures, intervalMs));
|
|
223
236
|
}
|
|
224
237
|
}
|
|
225
238
|
};
|