@astrale-os/kernel-protocol 0.5.0-beta.61 → 0.5.0-beta.62
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/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/errors/retry.d.ts +23 -0
- package/dist/errors/retry.js +44 -0
- package/package.json +3 -3
package/dist/errors/index.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export { httpStatusOf } from './http-status.js';
|
|
|
3
3
|
export { acceptPayload, type ErrorPayload } from './payload.js';
|
|
4
4
|
export { ProtocolError } from './protocol-error.js';
|
|
5
5
|
export { acceptReason, reasonOf, type ErrorReason } from './reason.js';
|
|
6
|
+
export { MAXIMUM_RETRY_AFTER_MS, RETRY_REASONS, retryAfterField, retryAfterOf, retryReason, type RetryReason, type RetryReasonCode, } from './retry.js';
|
package/dist/errors/index.js
CHANGED
|
@@ -3,3 +3,4 @@ export { httpStatusOf } from './http-status.js';
|
|
|
3
3
|
export { acceptPayload } from './payload.js';
|
|
4
4
|
export { ProtocolError } from './protocol-error.js';
|
|
5
5
|
export { acceptReason, reasonOf } from './reason.js';
|
|
6
|
+
export { MAXIMUM_RETRY_AFTER_MS, RETRY_REASONS, retryAfterField, retryAfterOf, retryReason, } from './retry.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ErrorPayload } from './payload.js';
|
|
2
|
+
import type { ErrorReason } from './reason.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reasons for a request refused before any work was admitted. The same request may be sent again
|
|
5
|
+
* once `retryAfterMs` has elapsed; every other public error keeps its own retry meaning.
|
|
6
|
+
*/
|
|
7
|
+
export declare const RETRY_REASONS: Readonly<{
|
|
8
|
+
/** A bounded Kernel resource is exhausted. */
|
|
9
|
+
readonly CAPACITY_EXHAUSTED: 'CAPACITY_EXHAUSTED';
|
|
10
|
+
/** The server stopped admitting work before it shuts down. */
|
|
11
|
+
readonly SERVER_DRAINING: 'SERVER_DRAINING';
|
|
12
|
+
}>;
|
|
13
|
+
export type RetryReasonCode = (typeof RETRY_REASONS)[keyof typeof RETRY_REASONS];
|
|
14
|
+
export type RetryReason<Code extends RetryReasonCode = RetryReasonCode> = ErrorReason<Code, {
|
|
15
|
+
readonly retryAfterMs: number;
|
|
16
|
+
}>;
|
|
17
|
+
/** One hour bounds a hint that only schedules the next attempt. */
|
|
18
|
+
export declare const MAXIMUM_RETRY_AFTER_MS = 3600000;
|
|
19
|
+
export declare function retryReason<Code extends RetryReasonCode>(code: Code, retryAfterMs: number): RetryReason<Code>;
|
|
20
|
+
/** Return the retry delay of a back-pressure or draining refusal, and nothing for other errors. */
|
|
21
|
+
export declare function retryAfterOf(error: ErrorPayload): number | undefined;
|
|
22
|
+
/** Present a retry delay as an HTTP `Retry-After` delta in whole seconds, rounded up. */
|
|
23
|
+
export declare function retryAfterField(retryAfterMs: number): string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CODES } from './codes.js';
|
|
2
|
+
import { reasonOf } from './reason.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reasons for a request refused before any work was admitted. The same request may be sent again
|
|
5
|
+
* once `retryAfterMs` has elapsed; every other public error keeps its own retry meaning.
|
|
6
|
+
*/
|
|
7
|
+
export const RETRY_REASONS = Object.freeze({
|
|
8
|
+
/** A bounded Kernel resource is exhausted. */
|
|
9
|
+
CAPACITY_EXHAUSTED: 'CAPACITY_EXHAUSTED',
|
|
10
|
+
/** The server stopped admitting work before it shuts down. */
|
|
11
|
+
SERVER_DRAINING: 'SERVER_DRAINING',
|
|
12
|
+
});
|
|
13
|
+
/** One hour bounds a hint that only schedules the next attempt. */
|
|
14
|
+
export const MAXIMUM_RETRY_AFTER_MS = 3_600_000;
|
|
15
|
+
const CODES_SET = new Set(Object.values(RETRY_REASONS));
|
|
16
|
+
export function retryReason(code, retryAfterMs) {
|
|
17
|
+
if (!CODES_SET.has(code))
|
|
18
|
+
throw new TypeError('Retry reason code is invalid.');
|
|
19
|
+
if (!isRetryAfter(retryAfterMs))
|
|
20
|
+
throw new TypeError('Retry reason retryAfterMs is invalid.');
|
|
21
|
+
return Object.freeze({ code, details: Object.freeze({ retryAfterMs }) });
|
|
22
|
+
}
|
|
23
|
+
/** Return the retry delay of a back-pressure or draining refusal, and nothing for other errors. */
|
|
24
|
+
export function retryAfterOf(error) {
|
|
25
|
+
if (error.code !== CODES.BACKEND_UNAVAILABLE)
|
|
26
|
+
return undefined;
|
|
27
|
+
const reason = reasonOf(error.data);
|
|
28
|
+
if (reason === undefined || !CODES_SET.has(reason.code))
|
|
29
|
+
return undefined;
|
|
30
|
+
const retryAfterMs = reason.details.retryAfterMs;
|
|
31
|
+
return isRetryAfter(retryAfterMs) ? retryAfterMs : undefined;
|
|
32
|
+
}
|
|
33
|
+
/** Present a retry delay as an HTTP `Retry-After` delta in whole seconds, rounded up. */
|
|
34
|
+
export function retryAfterField(retryAfterMs) {
|
|
35
|
+
if (!isRetryAfter(retryAfterMs))
|
|
36
|
+
throw new TypeError('Retry-After delay is invalid.');
|
|
37
|
+
return String(Math.ceil(retryAfterMs / 1_000));
|
|
38
|
+
}
|
|
39
|
+
function isRetryAfter(input) {
|
|
40
|
+
return (typeof input === 'number' &&
|
|
41
|
+
Number.isSafeInteger(input) &&
|
|
42
|
+
input >= 0 &&
|
|
43
|
+
input <= MAXIMUM_RETRY_AFTER_MS);
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/kernel-protocol",
|
|
3
|
-
"version": "0.5.0-beta.
|
|
3
|
+
"version": "0.5.0-beta.62",
|
|
4
4
|
"description": "Portable Astrale invocation, publication, installation, routing, and issuer protocols",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -137,8 +137,8 @@
|
|
|
137
137
|
"access": "public"
|
|
138
138
|
},
|
|
139
139
|
"dependencies": {
|
|
140
|
-
"@astrale-os/kernel-core": "0.9.0-beta.
|
|
141
|
-
"@astrale-os/kernel-dsl": "0.2.0-beta.
|
|
140
|
+
"@astrale-os/kernel-core": "0.9.0-beta.56",
|
|
141
|
+
"@astrale-os/kernel-dsl": "0.2.0-beta.41",
|
|
142
142
|
"@noble/hashes": "2.3.0"
|
|
143
143
|
},
|
|
144
144
|
"devDependencies": {
|