abysshub 0.0.1-dev.14 → 0.0.1-dev.15
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.
- package/README.md +4 -2
- package/dist/client.js +14 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ const run = await abyss.run(widget, input, { maxPrice, idempotencyKey, timeout,
|
|
|
48
48
|
- **`maxPrice`:** the most the run may cost, in Byssium. A higher price is refused with `price_above_max`, and nothing is charged.
|
|
49
49
|
- **`idempotencyKey`:** each call presses with a fresh UUID `Idempotency-Key` unless you give one. Retries send the same one, so a run is never made or charged twice.
|
|
50
50
|
|
|
51
|
-
The press holds until the run ends. When the hold ends early (a deploy cuts it, the API's holds are all taken, or an hour passes), `run()` re-attaches with `GET <Location>?wait=true` until the run ends. Re-attaching has no limit and is not a retry. Connecting has 10 s, and 30 s of silence counts as a cut.
|
|
51
|
+
The press holds until the run ends. When the hold ends early (a deploy cuts it, the network goes down, the API's holds are all taken, or an hour passes), `run()` re-attaches with `GET <Location>?wait=true` until the run ends. Re-attaching has no limit and is not a retry. Connecting has 10 s, and 30 s of silence counts as a cut.
|
|
52
52
|
|
|
53
53
|
A **run** has `/v1`'s fields: `id`, `widget`, `status` (`queued`, `running`, `succeeded` or `failed`), `price`, `result`, `output_files`, `error`, `created_at`, `started_at` and `ended_at`.
|
|
54
54
|
|
|
@@ -123,7 +123,9 @@ A request is sent again, at most `maxRetries` times (2 by default), only after:
|
|
|
123
123
|
- **`429 rate_limited` and `409 idempotency_key_in_use`:** after the `Retry-After` seconds;
|
|
124
124
|
- **a `5xx`:** a short backoff (0.5 s, then 1 s).
|
|
125
125
|
|
|
126
|
-
When the last try fails too, it raises. Every other refusal raises at once
|
|
126
|
+
When the last try fails too, it raises. Every other refusal raises at once.
|
|
127
|
+
|
|
128
|
+
**Re-attaching never counts as a retry.** A re-attach that drops, or meets a `429`, `409` or `5xx`, is tried again with no limit until the network is back, pausing 0.5 s and doubling to at most 10 s (or the `Retry-After` seconds). Only `timeout` and `signal` stop it.
|
|
127
129
|
|
|
128
130
|
## Timeouts
|
|
129
131
|
|
package/dist/client.js
CHANGED
|
@@ -10,6 +10,8 @@ const DEV_KEY_PREFIX = "abyss_sk_dev_";
|
|
|
10
10
|
const REATTACH_PAUSE_MS = 1_000;
|
|
11
11
|
/** The first pause before a retry after a drop or a 5xx; it doubles with each retry. */
|
|
12
12
|
const RETRY_PAUSE_MS = 500;
|
|
13
|
+
/** The longest pause between two tries, which only re-attaching, with no limit, reaches. */
|
|
14
|
+
const RETRY_PAUSE_CEILING_MS = 10_000;
|
|
13
15
|
const BROWSER_REFUSAL = "An Abyss API key is a server-side secret. Call the API from your server.";
|
|
14
16
|
const USER_AGENT = `abysshub-js/${VERSION} (${runtime()})`;
|
|
15
17
|
export class Abyss {
|
|
@@ -171,12 +173,16 @@ export class Abyss {
|
|
|
171
173
|
async #get(call, url, is, message) {
|
|
172
174
|
return expect(await this.#send(call, "GET", url), is, message);
|
|
173
175
|
}
|
|
174
|
-
/**
|
|
176
|
+
/**
|
|
177
|
+
* Reads `url` until `done`. Re-attaching has no limit and is not a retry: a re-attach
|
|
178
|
+
* that drops, or meets a `429`, `409` or `5xx`, is tried again until the network is
|
|
179
|
+
* back, and only the call's `timeout` or `signal` stops it.
|
|
180
|
+
*/
|
|
175
181
|
async #hold(call, url, done) {
|
|
176
|
-
let reply = await this.#send(call, "GET", url);
|
|
182
|
+
let reply = await this.#send(call, "GET", url, {}, undefined, Infinity);
|
|
177
183
|
while (!done(reply)) {
|
|
178
184
|
await sleep(REATTACH_PAUSE_MS, call.signal);
|
|
179
|
-
reply = await this.#send(call, "GET", url);
|
|
185
|
+
reply = await this.#send(call, "GET", url, {}, undefined, Infinity);
|
|
180
186
|
}
|
|
181
187
|
return reply;
|
|
182
188
|
}
|
|
@@ -201,9 +207,9 @@ export class Abyss {
|
|
|
201
207
|
}
|
|
202
208
|
/**
|
|
203
209
|
* Sends one request to `/v1`. A drop before any headers, a `429`, a `409` and a `5xx`
|
|
204
|
-
* are sent again, at most `
|
|
210
|
+
* are sent again, at most `retries` times; every other refusal raises at once.
|
|
205
211
|
*/
|
|
206
|
-
async #send(call, method, url, headers = {}, body) {
|
|
212
|
+
async #send(call, method, url, headers = {}, body, retries = this.maxRetries) {
|
|
207
213
|
const init = {
|
|
208
214
|
method,
|
|
209
215
|
headers: { Authorization: `Bearer ${this.#apiKey}`, Accept: "application/json", "User-Agent": USER_AGENT, ...headers },
|
|
@@ -218,7 +224,7 @@ export class Abyss {
|
|
|
218
224
|
catch (error) {
|
|
219
225
|
if (call.signal?.aborted)
|
|
220
226
|
throw error;
|
|
221
|
-
if (attempt >=
|
|
227
|
+
if (attempt >= retries) {
|
|
222
228
|
throw new AbyssError({
|
|
223
229
|
code: "connection_error",
|
|
224
230
|
message: "The connection dropped, or timed out, before the API answered.",
|
|
@@ -237,7 +243,7 @@ export class Abyss {
|
|
|
237
243
|
return { body: parsed, run, cut: answer.text === null, location: answer.headers.get("location"), requestId };
|
|
238
244
|
}
|
|
239
245
|
const pause = retryPause(answer, attempt);
|
|
240
|
-
if (pause === null || attempt >=
|
|
246
|
+
if (pause === null || attempt >= retries)
|
|
241
247
|
throw refusal(answer.status, parsed, requestId);
|
|
242
248
|
await sleep(pause, call.signal);
|
|
243
249
|
}
|
|
@@ -253,7 +259,7 @@ function retryPause(answer, attempt) {
|
|
|
253
259
|
return answer.status >= 500 ? backoff(attempt) : null;
|
|
254
260
|
}
|
|
255
261
|
function backoff(attempt) {
|
|
256
|
-
return RETRY_PAUSE_MS * 2 ** attempt;
|
|
262
|
+
return Math.min(RETRY_PAUSE_MS * 2 ** attempt, RETRY_PAUSE_CEILING_MS);
|
|
257
263
|
}
|
|
258
264
|
/** The reply's body when it is what the route answers, else `unexpected_response`. */
|
|
259
265
|
function expect(reply, is, message) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** This package's version, written from package.json by scripts/version.js at build. */
|
|
2
|
-
export declare const VERSION = "0.0.1-dev.
|
|
2
|
+
export declare const VERSION = "0.0.1-dev.15";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** This package's version, written from package.json by scripts/version.js at build. */
|
|
2
|
-
export const VERSION = "0.0.1-dev.
|
|
2
|
+
export const VERSION = "0.0.1-dev.15";
|
package/package.json
CHANGED