@noodleseed/one 0.22.0 → 0.23.0
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/commands/author-loop.d.ts.map +1 -1
- package/dist/commands/author-loop.js +2 -2
- package/dist/commands/author-loop.js.map +1 -1
- package/dist/commands/catalog-dispatch.d.ts.map +1 -1
- package/dist/commands/catalog-dispatch.js +21 -2
- package/dist/commands/catalog-dispatch.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +28 -11
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/first-run.d.ts +11 -0
- package/dist/first-run.d.ts.map +1 -1
- package/dist/first-run.js +19 -4
- package/dist/first-run.js.map +1 -1
- package/dist/project-scaffold-templates.d.ts +11 -0
- package/dist/project-scaffold-templates.d.ts.map +1 -0
- package/dist/project-scaffold-templates.js +359 -0
- package/dist/project-scaffold-templates.js.map +1 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +1 -323
- package/dist/project.js.map +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/validate.d.ts +12 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +11 -0
- package/dist/validate.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js +6 -9
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts +3 -3
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.js +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/components.d.ts +302 -7
- package/node_modules/@noodle-borg/authoring/dist/react/components.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/components.js +39 -7
- package/node_modules/@noodle-borg/authoring/dist/react/components.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/index.d.ts +4 -2
- package/node_modules/@noodle-borg/authoring/dist/react/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/index.js +2 -1
- package/node_modules/@noodle-borg/authoring/dist/react/index.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/semantic-components.d.ts +2618 -0
- package/node_modules/@noodle-borg/authoring/dist/react/semantic-components.d.ts.map +1 -0
- package/node_modules/@noodle-borg/authoring/dist/react/semantic-components.js +110 -0
- package/node_modules/@noodle-borg/authoring/dist/react/semantic-components.js.map +1 -0
- package/node_modules/@noodle-borg/authoring/dist/react.d.ts +2 -2
- package/node_modules/@noodle-borg/authoring/dist/react.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react.js +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.d.ts +1 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.js +14 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +25 -2
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +7 -3
- package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.js +20 -8
- package/node_modules/@noodle-borg/compiler/dist/compile.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +2 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +6 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js.map +1 -1
- package/node_modules/@noodle-borg/connector-http/package.json +1 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.js +8 -0
- package/node_modules/@noodle-borg/protocol/dist/mapping.js.map +1 -1
- package/node_modules/hono/dist/adapter/aws-lambda/handler.js +15 -21
- package/node_modules/hono/dist/adapter/bun/websocket.js +3 -1
- package/node_modules/hono/dist/adapter/lambda-edge/handler.js +8 -2
- package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +15 -21
- package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +3 -1
- package/node_modules/hono/dist/cjs/adapter/lambda-edge/handler.js +8 -2
- package/node_modules/hono/dist/cjs/helper/css/common.js +3 -1
- package/node_modules/hono/dist/cjs/helper/css/index.js +9 -1
- package/node_modules/hono/dist/cjs/jsx/base.js +8 -14
- package/node_modules/hono/dist/cjs/jsx/components.js +41 -21
- package/node_modules/hono/dist/cjs/jsx/context.js +131 -5
- package/node_modules/hono/dist/cjs/jsx/streaming.js +9 -7
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +2 -5
- package/node_modules/hono/dist/cjs/middleware/serve-static/index.js +2 -2
- package/node_modules/hono/dist/cjs/utils/body.js +12 -4
- package/node_modules/hono/dist/cjs/utils/buffer.js +2 -1
- package/node_modules/hono/dist/cjs/validator/validator.js +3 -3
- package/node_modules/hono/dist/helper/css/common.js +3 -1
- package/node_modules/hono/dist/helper/css/index.js +9 -1
- package/node_modules/hono/dist/jsx/base.js +15 -15
- package/node_modules/hono/dist/jsx/components.js +42 -22
- package/node_modules/hono/dist/jsx/context.js +129 -5
- package/node_modules/hono/dist/jsx/streaming.js +10 -8
- package/node_modules/hono/dist/middleware/cors/index.js +2 -5
- package/node_modules/hono/dist/middleware/serve-static/index.js +2 -2
- package/node_modules/hono/dist/types/adapter/aws-lambda/handler.d.ts +1 -1
- package/node_modules/hono/dist/types/jsx/base.d.ts +1 -3
- package/node_modules/hono/dist/types/jsx/context.d.ts +39 -0
- package/node_modules/hono/dist/types/middleware/context-storage/index.d.ts +2 -2
- package/node_modules/hono/dist/types/utils/body.d.ts +1 -1
- package/node_modules/hono/dist/utils/body.js +12 -4
- package/node_modules/hono/dist/utils/buffer.js +2 -1
- package/node_modules/hono/dist/validator/validator.js +3 -3
- package/node_modules/hono/package.json +9 -10
- package/node_modules/tailwindcss/dist/chunk-HMCCH6MG.mjs +1 -0
- package/node_modules/tailwindcss/dist/default-theme.mjs +1 -1
- package/node_modules/tailwindcss/dist/lib.js +13 -13
- package/node_modules/tailwindcss/dist/lib.mjs +18 -18
- package/node_modules/tailwindcss/package.json +2 -2
- package/node_modules/undici/README.md +3 -2
- package/node_modules/undici/docs/docs/api/Agent.md +248 -44
- package/node_modules/undici/docs/docs/api/BalancedPool.md +246 -48
- package/node_modules/undici/docs/docs/api/CacheStorage.md +171 -13
- package/node_modules/undici/docs/docs/api/CacheStore.md +294 -98
- package/node_modules/undici/docs/docs/api/Client.md +365 -178
- package/node_modules/undici/docs/docs/api/ClientStats.md +80 -14
- package/node_modules/undici/docs/docs/api/Connector.md +118 -36
- package/node_modules/undici/docs/docs/api/ContentType.md +65 -25
- package/node_modules/undici/docs/docs/api/Cookies.md +125 -47
- package/node_modules/undici/docs/docs/api/Debug.md +34 -18
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +364 -164
- package/node_modules/undici/docs/docs/api/Dispatcher.md +479 -1093
- package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +101 -87
- package/node_modules/undici/docs/docs/api/Errors.md +503 -40
- package/node_modules/undici/docs/docs/api/EventSource.md +294 -32
- package/node_modules/undici/docs/docs/api/Fetch.md +680 -31
- package/node_modules/undici/docs/docs/api/GlobalInstallation.md +78 -98
- package/node_modules/undici/docs/docs/api/H2CClient.md +298 -176
- package/node_modules/undici/docs/docs/api/Interceptors.md +355 -0
- package/node_modules/undici/docs/docs/api/MockAgent.md +314 -322
- package/node_modules/undici/docs/docs/api/MockCallHistory.md +272 -98
- package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +189 -26
- package/node_modules/undici/docs/docs/api/MockClient.md +151 -33
- package/node_modules/undici/docs/docs/api/MockErrors.md +56 -5
- package/node_modules/undici/docs/docs/api/MockPool.md +299 -263
- package/node_modules/undici/docs/docs/api/Pool.md +235 -43
- package/node_modules/undici/docs/docs/api/PoolStats.md +119 -13
- package/node_modules/undici/docs/docs/api/ProxyAgent.md +179 -160
- package/node_modules/undici/docs/docs/api/RedirectHandler.md +238 -63
- package/node_modules/undici/docs/docs/api/RetryAgent.md +113 -26
- package/node_modules/undici/docs/docs/api/RetryHandler.md +161 -77
- package/node_modules/undici/docs/docs/api/RoundRobinPool.md +166 -72
- package/node_modules/undici/docs/docs/api/SnapshotAgent.md +264 -542
- package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +162 -186
- package/node_modules/undici/docs/docs/api/Util.md +68 -11
- package/node_modules/undici/docs/docs/api/WebSocket.md +475 -80
- package/node_modules/undici/docs/docs/api/api-lifecycle.md +100 -32
- package/node_modules/undici/docs/docs/best-practices/client-certificate.md +2 -0
- package/node_modules/undici/docs/docs/best-practices/crawling.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +6 -4
- package/node_modules/undici/docs/docs/best-practices/mocking-request.md +9 -7
- package/node_modules/undici/docs/docs/best-practices/proxy.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +10 -8
- package/node_modules/undici/docs/docs/best-practices/writing-tests.md +2 -0
- package/node_modules/undici/docs/docs/{GettingStarted.md → getting-started.md} +22 -19
- package/node_modules/undici/docs/docs/index.md +779 -0
- package/node_modules/undici/docs/docs/site.json +125 -0
- package/node_modules/undici/docs/docs/type-map.json +79 -0
- package/node_modules/undici/lib/api/api-request.js +7 -1
- package/node_modules/undici/lib/api/readable.js +47 -2
- package/node_modules/undici/lib/core/errors.js +20 -0
- package/node_modules/undici/lib/core/request.js +1 -1
- package/node_modules/undici/lib/core/util.js +24 -1
- package/node_modules/undici/lib/dispatcher/client-h1.js +92 -1
- package/node_modules/undici/lib/dispatcher/client-h2.js +322 -118
- package/node_modules/undici/lib/dispatcher/client.js +6 -2
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +1 -0
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +42 -7
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +4 -2
- package/node_modules/undici/lib/handler/redirect-handler.js +1 -0
- package/node_modules/undici/lib/handler/retry-handler.js +57 -19
- package/node_modules/undici/lib/util/cache.js +8 -2
- package/node_modules/undici/lib/web/cookies/parse.js +20 -27
- package/node_modules/undici/lib/web/cookies/util.js +1 -1
- package/node_modules/undici/lib/web/eventsource/eventsource.js +7 -18
- package/node_modules/undici/lib/web/eventsource/util.js +32 -1
- package/node_modules/undici/lib/web/fetch/body.js +43 -0
- package/node_modules/undici/lib/web/fetch/constants.js +1 -1
- package/node_modules/undici/lib/web/fetch/index.js +11 -2
- package/node_modules/undici/lib/web/fetch/request.js +1 -0
- package/node_modules/undici/lib/web/fetch/util.js +4 -1
- package/node_modules/undici/lib/web/websocket/receiver.js +20 -3
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -1
- package/node_modules/undici/lib/web/websocket/websocket.js +3 -1
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/client.d.ts +6 -1
- package/node_modules/undici/types/cookies.d.ts +1 -1
- package/node_modules/undici/types/errors.d.ts +10 -0
- package/node_modules/undici/types/fetch.d.ts +1 -0
- package/node_modules/undici/types/handlers.d.ts +2 -0
- package/node_modules/undici/types/proxy-agent.d.ts +7 -0
- package/package.json +4 -4
- package/react/styles.css +510 -5
- package/react/styles.source.css +850 -0
- package/node_modules/hono/dist/tsconfig.build.tsbuildinfo +0 -1
- package/node_modules/tailwindcss/dist/chunk-XVOTX5KS.mjs +0 -1
|
@@ -1,116 +1,200 @@
|
|
|
1
|
-
#
|
|
1
|
+
# RetryHandler
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<!--introduced_in=v5.28.0-->
|
|
4
|
+
<!--type=module-->
|
|
5
|
+
<!-- source_link=lib/handler/retry-handler.js -->
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
> Stability: 2 - Stable
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
A [`Dispatcher`][] handler that automatically retries a request when it fails
|
|
10
|
+
with a recoverable network error or an eligible HTTP status code. It wraps an
|
|
11
|
+
inner handler and re-dispatches the request, applying an exponential backoff and
|
|
12
|
+
honouring the `Retry-After` response header. When a response is partially
|
|
13
|
+
consumed before the failure, the handler resumes the download with a `Range`
|
|
14
|
+
request guarded by the original `ETag`.
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
The handler is most often used indirectly through [`RetryAgent`][], but it can
|
|
17
|
+
also be supplied directly to [`dispatcher.dispatch()`][] for fine-grained
|
|
18
|
+
control over the retry behaviour.
|
|
10
19
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Returns: `retryHandler`
|
|
15
|
-
|
|
16
|
-
### Parameter: `Dispatch.DispatchOptions & RetryOptions`
|
|
17
|
-
|
|
18
|
-
Extends: [`Dispatch.DispatchOptions`](/docs/docs/api/Dispatcher.md#parameter-dispatchoptions).
|
|
19
|
-
|
|
20
|
-
#### `RetryOptions`
|
|
20
|
+
```mjs
|
|
21
|
+
import { RetryHandler } from 'undici'
|
|
22
|
+
```
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
- **retry** `(err: Error, context: RetryContext, callback: (err?: Error | null) => void) => void` (optional) - Function to be called after every retry. It should pass error if no more retries should be performed.
|
|
24
|
-
- **maxRetries** `number` (optional) - Maximum number of retries. Default: `5`
|
|
25
|
-
- **maxTimeout** `number` (optional) - Maximum number of milliseconds to wait before retrying. Default: `30000` (30 seconds)
|
|
26
|
-
- **minTimeout** `number` (optional) - Minimum number of milliseconds to wait before retrying. Default: `500` (half a second)
|
|
27
|
-
- **timeoutFactor** `number` (optional) - Factor to multiply the timeout by for each retry attempt. Default: `2`
|
|
28
|
-
- **retryAfter** `boolean` (optional) - It enables automatic retry after the `Retry-After` header is received. Default: `true`
|
|
29
|
-
- **methods** `string[]` (optional) - Array of HTTP methods to retry. Default: `['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE']`
|
|
30
|
-
- **statusCodes** `number[]` (optional) - Array of HTTP status codes to retry. Default: `[429, 500, 502, 503, 504]`
|
|
31
|
-
- **errorCodes** `string[]` (optional) - Array of Error codes to retry. Default: `['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN', 'ENETUNREACH', 'EHOSTDOWN', 'EHOSTUNREACH', 'EPIPE', 'UND_ERR_SOCKET']`
|
|
24
|
+
## Class: `RetryHandler`
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
<!-- YAML
|
|
27
|
+
added: v5.28.0
|
|
28
|
+
-->
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
- `opts`: `Dispatch.DispatchOptions & RetryOptions` - Options passed to the retry handler.
|
|
30
|
+
* Extends: {DispatchHandler}
|
|
37
31
|
|
|
38
|
-
|
|
32
|
+
Implements the [`DispatchHandler`][] interface. An instance is consumed by a
|
|
33
|
+
single dispatch call and forwards the dispatch lifecycle to the inner `handler`,
|
|
34
|
+
re-issuing the request through the supplied `dispatch` function whenever a retry
|
|
35
|
+
is warranted.
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
> **Note:** The `RetryHandler` does not retry over stateful bodies (for example
|
|
38
|
+
> streams or `AsyncIterable`), because once consumed they cannot be replayed. In
|
|
39
|
+
> these situations the body is identified as stateful and the request is rejected
|
|
40
|
+
> with the `UND_ERR_REQ_RETRY` error instead of being retried.
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
### `new RetryHandler(options, retryHandlers)`
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
<!-- YAML
|
|
45
|
+
added: v5.28.0
|
|
46
|
+
changes:
|
|
47
|
+
- version: v7.0.0
|
|
48
|
+
pr-url: https://github.com/nodejs/undici/pull/3883
|
|
49
|
+
description: Reimplemented on top of the new dispatch lifecycle hooks.
|
|
50
|
+
-->
|
|
45
51
|
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
* `options` {DispatchOptions} The dispatch options for the request, extended with
|
|
53
|
+
an optional `retryOptions` field. Type is
|
|
54
|
+
`DispatchOptions & { retryOptions?: RetryOptions }`.
|
|
55
|
+
* `retryOptions` {RetryOptions} (optional) Configuration controlling when and
|
|
56
|
+
how the request is retried. See [`RetryOptions`](#retryoptions).
|
|
57
|
+
* `retryHandlers` {RetryHandlers} The handlers used to drive the retry loop. See
|
|
58
|
+
[`RetryHandlers`](#parameter-retryhandlers).
|
|
59
|
+
* Returns: {RetryHandler}
|
|
48
60
|
|
|
49
|
-
|
|
50
|
-
>the body as stateful and will not retry the request rejecting with the error `UND_ERR_REQ_RETRY`.
|
|
61
|
+
#### `RetryOptions`
|
|
51
62
|
|
|
52
|
-
|
|
63
|
+
* `throwOnError` {boolean} When `true`, an error is thrown on the last retry
|
|
64
|
+
attempt and propagated to the inner handler; when `false`, the failing response
|
|
65
|
+
is passed through instead, which is useful when the error body is needed or a
|
|
66
|
+
custom error handler is in place. **Default:** `true`.
|
|
67
|
+
* `retry` {Function} Callback invoked on every retry iteration to decide whether
|
|
68
|
+
another attempt should be made. It receives the error, the retry context, and a
|
|
69
|
+
callback. Call the callback with an `Error` to stop retrying, or with `null` to
|
|
70
|
+
schedule another attempt. **Default:** the built-in retry strategy described
|
|
71
|
+
below.
|
|
72
|
+
* `err` {Error} The error that triggered the retry.
|
|
73
|
+
* `context` {RetryContext} The current retry context. See
|
|
74
|
+
[`RetryContext`](#retrycontext).
|
|
75
|
+
* `callback` {Function} Signals the outcome of this iteration.
|
|
76
|
+
* `result` {Error|null} (optional) An `Error` to abort retrying, or `null` to
|
|
77
|
+
retry.
|
|
78
|
+
* `maxRetries` {number} Maximum number of retries allowed. **Default:** `5`.
|
|
79
|
+
* `maxTimeout` {number} Maximum number of milliseconds to wait between retries.
|
|
80
|
+
**Default:** `30000` (30 seconds).
|
|
81
|
+
* `minTimeout` {number} Initial number of milliseconds to wait before the first
|
|
82
|
+
retry. **Default:** `500` (half a second).
|
|
83
|
+
* `timeoutFactor` {number} Multiplier applied to the timeout between successive
|
|
84
|
+
retries to produce an exponential backoff. **Default:** `2`.
|
|
85
|
+
* `retryAfter` {boolean} When `true`, the delay before the next retry is inferred
|
|
86
|
+
from the `Retry-After` response header when present. **Default:** `true`.
|
|
87
|
+
* `methods` {string[]} HTTP methods that are eligible for retrying. **Default:**
|
|
88
|
+
`['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE']`.
|
|
89
|
+
* `statusCodes` {number[]} HTTP status codes that trigger a retry. **Default:**
|
|
90
|
+
`[500, 502, 503, 504, 429]`.
|
|
91
|
+
* `errorCodes` {string[]} Network error codes that trigger a retry. **Default:**
|
|
92
|
+
`['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN', 'ENETUNREACH', 'EHOSTDOWN', 'EHOSTUNREACH', 'EPIPE', 'UND_ERR_SOCKET']`.
|
|
93
|
+
|
|
94
|
+
The default `retry` strategy computes the delay before the next attempt as
|
|
95
|
+
`minTimeout * timeoutFactor ** (counter - 1)`, capped at `maxTimeout`. When a
|
|
96
|
+
`Retry-After` header is present it takes precedence (interpreted as seconds, or as
|
|
97
|
+
an HTTP date), still capped at `maxTimeout`. The default strategy stops retrying
|
|
98
|
+
once `counter` exceeds `maxRetries`, when the error code is not in `errorCodes`,
|
|
99
|
+
when the method is not in `methods`, or when the response status code is not in
|
|
100
|
+
`statusCodes`.
|
|
101
|
+
|
|
102
|
+
#### `RetryContext`
|
|
103
|
+
|
|
104
|
+
* `state` {RetryState} The current retry state. See [`RetryState`](#retrystate).
|
|
105
|
+
* `opts` {DispatchOptions} The dispatch options passed to the handler, including
|
|
106
|
+
the resolved `retryOptions`. Type is
|
|
107
|
+
`DispatchOptions & { retryOptions?: RetryOptions }`.
|
|
108
|
+
|
|
109
|
+
The context object passed as the second argument to the `retry` callback.
|
|
110
|
+
|
|
111
|
+
#### `RetryState`
|
|
112
|
+
|
|
113
|
+
* `counter` {number} The current retry attempt, starting at `1` for the first
|
|
114
|
+
retry.
|
|
115
|
+
|
|
116
|
+
Represents the retry state for a given request.
|
|
117
|
+
|
|
118
|
+
#### Parameter: `RetryHandlers`
|
|
119
|
+
|
|
120
|
+
* `dispatch` {Function} The dispatch function called to (re-)issue the request on
|
|
121
|
+
every attempt. Type is `(options, handler) => boolean`.
|
|
122
|
+
* `handler` {DispatchHandler} The inner handler invoked once the request succeeds
|
|
123
|
+
or the retries are exhausted.
|
|
124
|
+
|
|
125
|
+
### Examples
|
|
126
|
+
|
|
127
|
+
```mjs
|
|
128
|
+
import { Client, RetryHandler } from 'undici'
|
|
129
|
+
|
|
130
|
+
const client = new Client(`http://localhost:${server.address().port}`)
|
|
131
|
+
const chunks = []
|
|
53
132
|
|
|
54
|
-
```js
|
|
55
|
-
const client = new Client(`http://localhost:${server.address().port}`);
|
|
56
|
-
const chunks = [];
|
|
57
133
|
const handler = new RetryHandler(
|
|
58
134
|
{
|
|
59
135
|
...dispatchOptions,
|
|
60
136
|
retryOptions: {
|
|
61
|
-
//
|
|
62
|
-
retry
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
callback(err);
|
|
67
|
-
return;
|
|
137
|
+
// Custom retry decision function.
|
|
138
|
+
retry (err, { state, opts }, callback) {
|
|
139
|
+
if (err.code === 'UND_ERR_DESTROYED') {
|
|
140
|
+
callback(err)
|
|
141
|
+
return
|
|
68
142
|
}
|
|
69
143
|
|
|
70
144
|
if (err.statusCode === 206) {
|
|
71
|
-
callback(err)
|
|
72
|
-
return
|
|
145
|
+
callback(err)
|
|
146
|
+
return
|
|
73
147
|
}
|
|
74
148
|
|
|
75
|
-
setTimeout(() => callback(null), 1000)
|
|
76
|
-
}
|
|
77
|
-
}
|
|
149
|
+
setTimeout(() => callback(null), 1000)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
78
152
|
},
|
|
79
153
|
{
|
|
80
|
-
dispatch
|
|
81
|
-
return client.dispatch(...args)
|
|
154
|
+
dispatch (...args) {
|
|
155
|
+
return client.dispatch(...args)
|
|
82
156
|
},
|
|
83
157
|
handler: {
|
|
84
|
-
onRequestStart() {},
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// do something with headers
|
|
158
|
+
onRequestStart () {},
|
|
159
|
+
onResponseStart (controller, status, headers) {
|
|
160
|
+
// Do something with the response headers.
|
|
88
161
|
},
|
|
89
|
-
onResponseData(
|
|
90
|
-
chunks.push(chunk)
|
|
162
|
+
onResponseData (controller, chunk) {
|
|
163
|
+
chunks.push(chunk)
|
|
91
164
|
},
|
|
92
|
-
onResponseEnd() {},
|
|
93
|
-
onResponseError(
|
|
94
|
-
//
|
|
95
|
-
}
|
|
96
|
-
}
|
|
165
|
+
onResponseEnd () {},
|
|
166
|
+
onResponseError (controller, err) {
|
|
167
|
+
// Handle the error.
|
|
168
|
+
}
|
|
169
|
+
}
|
|
97
170
|
}
|
|
98
|
-
)
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
client.dispatch(dispatchOptions, handler)
|
|
99
174
|
```
|
|
100
175
|
|
|
101
|
-
|
|
176
|
+
A minimal handler that relies entirely on the default retry options:
|
|
177
|
+
|
|
178
|
+
```mjs
|
|
179
|
+
import { Client, RetryHandler } from 'undici'
|
|
180
|
+
|
|
181
|
+
const client = new Client(`http://localhost:${server.address().port}`)
|
|
102
182
|
|
|
103
|
-
```js
|
|
104
|
-
const client = new Client(`http://localhost:${server.address().port}`);
|
|
105
183
|
const handler = new RetryHandler(dispatchOptions, {
|
|
106
184
|
dispatch: client.dispatch.bind(client),
|
|
107
185
|
handler: {
|
|
108
|
-
onRequestStart() {},
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
186
|
+
onRequestStart () {},
|
|
187
|
+
onResponseStart (controller, status, headers) {},
|
|
188
|
+
onResponseData (controller, chunk) {},
|
|
189
|
+
onResponseEnd () {},
|
|
190
|
+
onResponseError (controller, err) {}
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
client.dispatch(dispatchOptions, handler)
|
|
116
195
|
```
|
|
196
|
+
|
|
197
|
+
[`Dispatcher`]: Dispatcher.md#class-dispatcher
|
|
198
|
+
[`DispatchHandler`]: Dispatcher.md#parameter-dispatchhandler
|
|
199
|
+
[`RetryAgent`]: RetryAgent.md#class-retryagent
|
|
200
|
+
[`dispatcher.dispatch()`]: Dispatcher.md#dispatcherdispatchoptions-handler
|
|
@@ -1,131 +1,213 @@
|
|
|
1
|
-
#
|
|
1
|
+
# RoundRobinPool
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<!--introduced_in=v7.17.0-->
|
|
4
|
+
<!--type=module-->
|
|
5
|
+
<!-- source_link=lib/dispatcher/round-robin-pool.js -->
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
> Stability: 2 - Stable
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
A pool of [`Client`][] instances connected to the same upstream target that
|
|
10
|
+
selects clients in a round-robin fashion.
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
Unlike [`Pool`][], which always reuses the first available client,
|
|
13
|
+
`RoundRobinPool` cycles through its clients so that requests are distributed
|
|
14
|
+
evenly across every open connection. This is useful when the upstream target is
|
|
15
|
+
fronted by a load balancer that distributes TCP connections across multiple
|
|
16
|
+
backend servers (for example, a Kubernetes Service): each connection is pinned
|
|
17
|
+
to a backend by the load balancer, and `RoundRobinPool` spreads requests across
|
|
18
|
+
those connections so every backend receives a comparable share of traffic.
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
Requests are not guaranteed to be dispatched in the order they were invoked.
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
```mjs
|
|
23
|
+
import { RoundRobinPool } from 'undici'
|
|
24
|
+
|
|
25
|
+
const pool = new RoundRobinPool('http://localhost:3000', { connections: 10 })
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`RoundRobinPool` distributes HTTP requests evenly across TCP connections, not
|
|
29
|
+
across backend servers directly. Even backend distribution therefore depends on
|
|
30
|
+
the load balancer assigning different connections to different backends (for
|
|
31
|
+
example, round-robin, random, or least-connections without client affinity). If
|
|
32
|
+
the load balancer pins all connections from one source to the same backend (for
|
|
33
|
+
example, source-IP affinity or sticky sessions), consider [`BalancedPool`][]
|
|
34
|
+
with the individual backend addresses instead.
|
|
35
|
+
|
|
36
|
+
## Class: `RoundRobinPool`
|
|
37
|
+
|
|
38
|
+
<!-- YAML
|
|
39
|
+
added: v7.17.0
|
|
40
|
+
-->
|
|
41
|
+
|
|
42
|
+
* Extends: {Dispatcher}
|
|
43
|
+
|
|
44
|
+
### `new RoundRobinPool(url[, options])`
|
|
14
45
|
|
|
15
|
-
|
|
16
|
-
|
|
46
|
+
<!-- YAML
|
|
47
|
+
added: v7.17.0
|
|
48
|
+
-->
|
|
17
49
|
|
|
18
|
-
|
|
50
|
+
* `url` {URL|string} The upstream target. It should only include the
|
|
51
|
+
**protocol, hostname, and port**.
|
|
52
|
+
* `options` {RoundRobinPoolOptions} (optional)
|
|
19
53
|
|
|
20
|
-
|
|
54
|
+
#### Parameter: `RoundRobinPoolOptions`
|
|
21
55
|
|
|
22
|
-
|
|
23
|
-
* **connections** `number | null` (optional) - Default: `null` - The number of `Client` instances to create. When set to `null`, the `RoundRobinPool` instance will create an unlimited amount of `Client` instances.
|
|
24
|
-
* **clientTtl** `number | null` (optional) - Default: `null` - The amount of time before a `Client` instance is removed from the `RoundRobinPool` and closed. When set to `null`, `Client` instances will not be removed or closed based on age.
|
|
56
|
+
Extends: {ClientOptions}
|
|
25
57
|
|
|
26
|
-
|
|
58
|
+
* `factory` {Function} A function used to create the underlying {Client}
|
|
59
|
+
instances. **Default:** `(origin, opts) => new Client(origin, opts)`.
|
|
60
|
+
* `origin` {URL}
|
|
61
|
+
* `opts` {Object}
|
|
62
|
+
* Returns: {Dispatcher}
|
|
63
|
+
* `connections` {number|null} (optional) The maximum number of {Client}
|
|
64
|
+
instances to create. When set to `null`, the `RoundRobinPool` instance creates
|
|
65
|
+
an unlimited number of {Client} instances. **Default:** `null`.
|
|
66
|
+
* `clientTtl` {number|null} (optional) The amount of time, in milliseconds,
|
|
67
|
+
before a {Client} instance is removed from the `RoundRobinPool` and closed.
|
|
68
|
+
When set to `null`, {Client} instances are not removed or closed based on age.
|
|
69
|
+
**Default:** `null`.
|
|
27
70
|
|
|
28
|
-
`RoundRobinPool`
|
|
71
|
+
`RoundRobinPool` inherits all [`Client`][] options. A [`Client`][] instance is
|
|
72
|
+
created lazily on the first dispatch and additional instances are created on
|
|
73
|
+
demand, up to `connections`, when every existing client is busy.
|
|
29
74
|
|
|
30
|
-
|
|
31
|
-
2. That origin is backed by a load balancer distributing TCP connections across multiple servers
|
|
32
|
-
3. You want requests evenly distributed across all backend servers
|
|
75
|
+
### `roundRobinPool.closed`
|
|
33
76
|
|
|
34
|
-
|
|
77
|
+
<!-- YAML
|
|
78
|
+
added: v7.17.0
|
|
79
|
+
-->
|
|
35
80
|
|
|
36
|
-
|
|
81
|
+
* Type: {boolean}
|
|
37
82
|
|
|
38
|
-
`
|
|
83
|
+
`true` after `roundRobinPool.close()` has been called.
|
|
39
84
|
|
|
40
|
-
|
|
41
|
-
- Assigns different backends to different TCP connections from the same client
|
|
42
|
-
- Uses algorithms like: round-robin, random, least-connections (without client affinity)
|
|
43
|
-
- Example: Default Kubernetes Services without `sessionAffinity`
|
|
85
|
+
### `roundRobinPool.destroyed`
|
|
44
86
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
87
|
+
<!-- YAML
|
|
88
|
+
added: v7.17.0
|
|
89
|
+
-->
|
|
48
90
|
|
|
49
|
-
|
|
50
|
-
1. `RoundRobinPool` creates N TCP connections to the load balancer endpoint
|
|
51
|
-
2. Load balancer assigns each TCP connection to a backend (per its algorithm)
|
|
52
|
-
3. `RoundRobinPool` cycles HTTP requests across those N connections
|
|
53
|
-
4. Result: Requests distributed proportionally to how the LB distributed the connections
|
|
91
|
+
* Type: {boolean}
|
|
54
92
|
|
|
55
|
-
|
|
93
|
+
`true` after `roundRobinPool.destroy()` has been called, or after
|
|
94
|
+
`roundRobinPool.close()` has been called and the pool shutdown has completed.
|
|
56
95
|
|
|
57
|
-
|
|
96
|
+
### `roundRobinPool.stats`
|
|
58
97
|
|
|
59
|
-
|
|
98
|
+
<!-- YAML
|
|
99
|
+
added: v7.17.0
|
|
100
|
+
-->
|
|
60
101
|
|
|
61
|
-
|
|
102
|
+
* Type: {PoolStats}
|
|
62
103
|
|
|
63
|
-
|
|
104
|
+
Aggregate connection statistics for the pool. See [`PoolStats`][].
|
|
64
105
|
|
|
65
|
-
|
|
106
|
+
### `roundRobinPool.close([callback])`
|
|
66
107
|
|
|
67
|
-
|
|
108
|
+
<!-- YAML
|
|
109
|
+
added: v7.17.0
|
|
110
|
+
-->
|
|
68
111
|
|
|
69
|
-
|
|
112
|
+
Closes the pool and gracefully waits for enqueued requests to complete before
|
|
113
|
+
resolving. Implements [`dispatcher.close([callback])`][].
|
|
70
114
|
|
|
71
|
-
|
|
115
|
+
### `roundRobinPool.destroy([error[, callback]])`
|
|
72
116
|
|
|
73
|
-
|
|
117
|
+
<!-- YAML
|
|
118
|
+
added: v7.17.0
|
|
119
|
+
-->
|
|
74
120
|
|
|
75
|
-
|
|
121
|
+
Destroys the pool abruptly. All pending and running requests are aborted with
|
|
122
|
+
the given `error`. Implements [`dispatcher.destroy([error[, callback]])`][].
|
|
76
123
|
|
|
77
|
-
### `
|
|
124
|
+
### `roundRobinPool.connect(options[, callback])`
|
|
78
125
|
|
|
79
|
-
|
|
126
|
+
<!-- YAML
|
|
127
|
+
added: v7.17.0
|
|
128
|
+
-->
|
|
80
129
|
|
|
81
|
-
|
|
130
|
+
Starts two-way communications with the requested resource using
|
|
131
|
+
[HTTP CONNECT][]. See [`dispatcher.connect(options[, callback])`][].
|
|
82
132
|
|
|
83
|
-
|
|
133
|
+
### `roundRobinPool.dispatch(options, handler)`
|
|
84
134
|
|
|
85
|
-
|
|
135
|
+
<!-- YAML
|
|
136
|
+
added: v7.17.0
|
|
137
|
+
-->
|
|
86
138
|
|
|
87
|
-
|
|
139
|
+
Dispatches a request through the next client selected in round-robin order.
|
|
140
|
+
Implements [`dispatcher.dispatch(options, handler)`][].
|
|
88
141
|
|
|
89
|
-
### `
|
|
142
|
+
### `roundRobinPool.pipeline(options, handler)`
|
|
90
143
|
|
|
91
|
-
|
|
144
|
+
<!-- YAML
|
|
145
|
+
added: v7.17.0
|
|
146
|
+
-->
|
|
92
147
|
|
|
93
|
-
|
|
148
|
+
For easy use with [`stream.pipeline`][]. See
|
|
149
|
+
[`dispatcher.pipeline(options, handler)`][].
|
|
94
150
|
|
|
95
|
-
|
|
151
|
+
### `roundRobinPool.request(options[, callback])`
|
|
96
152
|
|
|
97
|
-
|
|
153
|
+
<!-- YAML
|
|
154
|
+
added: v7.17.0
|
|
155
|
+
-->
|
|
98
156
|
|
|
99
|
-
See [`
|
|
157
|
+
Performs an HTTP request. See [`dispatcher.request(options[, callback])`][].
|
|
100
158
|
|
|
101
|
-
### `
|
|
159
|
+
### `roundRobinPool.stream(options, factory[, callback])`
|
|
102
160
|
|
|
103
|
-
|
|
161
|
+
<!-- YAML
|
|
162
|
+
added: v7.17.0
|
|
163
|
+
-->
|
|
104
164
|
|
|
105
|
-
|
|
165
|
+
A faster version of [`roundRobinPool.request()`][]. See
|
|
166
|
+
[`dispatcher.stream(options, factory[, callback])`][].
|
|
167
|
+
|
|
168
|
+
### `roundRobinPool.upgrade(options[, callback])`
|
|
169
|
+
|
|
170
|
+
<!-- YAML
|
|
171
|
+
added: v7.17.0
|
|
172
|
+
-->
|
|
173
|
+
|
|
174
|
+
Upgrades a connection to a different protocol. See
|
|
175
|
+
[`dispatcher.upgrade(options[, callback])`][].
|
|
106
176
|
|
|
107
177
|
### Event: `'connect'`
|
|
108
178
|
|
|
109
|
-
|
|
179
|
+
<!-- YAML
|
|
180
|
+
added: v7.17.0
|
|
181
|
+
-->
|
|
182
|
+
|
|
183
|
+
See [Dispatcher Event: `'connect'`][].
|
|
110
184
|
|
|
111
185
|
### Event: `'disconnect'`
|
|
112
186
|
|
|
113
|
-
|
|
187
|
+
<!-- YAML
|
|
188
|
+
added: v7.17.0
|
|
189
|
+
-->
|
|
190
|
+
|
|
191
|
+
See [Dispatcher Event: `'disconnect'`][].
|
|
114
192
|
|
|
115
193
|
### Event: `'drain'`
|
|
116
194
|
|
|
117
|
-
|
|
195
|
+
<!-- YAML
|
|
196
|
+
added: v7.17.0
|
|
197
|
+
-->
|
|
198
|
+
|
|
199
|
+
See [Dispatcher Event: `'drain'`][].
|
|
118
200
|
|
|
119
201
|
## Example
|
|
120
202
|
|
|
121
|
-
```
|
|
203
|
+
```mjs
|
|
122
204
|
import { RoundRobinPool } from 'undici'
|
|
123
205
|
|
|
124
|
-
const pool = new RoundRobinPool('http://
|
|
206
|
+
const pool = new RoundRobinPool('http://localhost:3000', {
|
|
125
207
|
connections: 10
|
|
126
208
|
})
|
|
127
209
|
|
|
128
|
-
// Requests
|
|
210
|
+
// Requests are distributed evenly across all 10 connections.
|
|
129
211
|
for (let i = 0; i < 100; i++) {
|
|
130
212
|
const { body } = await pool.request({
|
|
131
213
|
path: '/api/data',
|
|
@@ -137,9 +219,21 @@ for (let i = 0; i < 100; i++) {
|
|
|
137
219
|
await pool.close()
|
|
138
220
|
```
|
|
139
221
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
222
|
+
[HTTP CONNECT]: https://developer.mozilla.org/docs/Web/HTTP/Methods/CONNECT
|
|
223
|
+
[`BalancedPool`]: BalancedPool.md#class-balancedpool
|
|
224
|
+
[`Client`]: Client.md#class-client
|
|
225
|
+
[`Pool`]: Pool.md#class-pool
|
|
226
|
+
[`PoolStats`]: PoolStats.md#class-poolstats
|
|
227
|
+
[`dispatcher.close([callback])`]: Dispatcher.md#dispatcherclosecallback-promise
|
|
228
|
+
[`dispatcher.connect(options[, callback])`]: Dispatcher.md#dispatcherconnectoptions-callback
|
|
229
|
+
[`dispatcher.destroy([error[, callback]])`]: Dispatcher.md#dispatcherdestroyerror-callback-promise
|
|
230
|
+
[`dispatcher.dispatch(options, handler)`]: Dispatcher.md#dispatcherdispatchoptions-handler
|
|
231
|
+
[`dispatcher.pipeline(options, handler)`]: Dispatcher.md#dispatcherpipelineoptions-handler
|
|
232
|
+
[`dispatcher.request(options[, callback])`]: Dispatcher.md#dispatcherrequestoptions-callback
|
|
233
|
+
[`dispatcher.stream(options, factory[, callback])`]: Dispatcher.md#dispatcherstreamoptions-factory-callback
|
|
234
|
+
[`dispatcher.upgrade(options[, callback])`]: Dispatcher.md#dispatcherupgradeoptions-callback
|
|
235
|
+
[`roundRobinPool.request()`]: #roundrobinpoolrequestoptions-callback
|
|
236
|
+
[`stream.pipeline`]: https://nodejs.org/api/stream.html#streampipelinesource-transforms-destination-callback
|
|
237
|
+
[Dispatcher Event: `'connect'`]: Dispatcher.md#event-connect
|
|
238
|
+
[Dispatcher Event: `'disconnect'`]: Dispatcher.md#event-disconnect
|
|
239
|
+
[Dispatcher Event: `'drain'`]: Dispatcher.md#event-drain
|