Skip to content

Commit

Permalink
refactor: Unify Client, Pool & Agent (#620)
Browse files Browse the repository at this point in the history
* refactor: Client.clients & Agent is a Client.

Refs: #616

* fixup: rename clientt to dispatcher

* fixup: keep promise chain

* fixup

* fixup

* fixup
  • Loading branch information
ronag committed Mar 31, 2021
1 parent c021f8b commit 9c04cfa
Show file tree
Hide file tree
Showing 18 changed files with 1,395 additions and 1,041 deletions.
104 changes: 104 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,110 @@ for await (const data of body) {
console.log('trailers', trailers)
```

## `undici.request(url[, options]): Promise`

Arguments:

* **url** `string | URL | object`
* **options** [`RequestOptions`]
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher]
* **method** `String` - Default: `GET`
* **maxRedirections** `Integer` - Default: `0`

Returns a promise with the result of the `Dispatcher.request` method.

`url` may contain pathname. `options` may not contain path.

Calls `options.dispatcher.request(options)`.

See [Dispatcher.request] for more details.

## `undici.stream(url, options, factory): Promise`

Arguments:

* **url** `string | URL | object`
* **options** [`StreamOptions`]
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher]
* **method** `String` - Default: `GET`
* **factory** `Dispatcher.stream.factory`

Returns a promise with the result of the `Dispatcher.stream` method.

`url` may contain pathname. `options` may not contain path.

Calls `options.dispatcher.stream(options, factory)`.

See [Dispatcher.stream](docs/api/Dispatcher.md#dispatcherstream) for more details.

## `undici.pipeline(url, options, handler): Duplex`

Arguments:

* **url** `string | URL | object`
* **options** [`PipelineOptions`]
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher]
* **method** `String` - Default: `GET`
* **handler** `Dispatcher.pipeline.handler`

Returns: `stream.Duplex`

`url` may contain pathname. `options` may not contain path.

Calls `options.dispatch.pipeline(options, handler)`.

See [Dispatcher.pipeline](docs/api/Dispatcher.md#dispatcherpipeline) for more details.

### `undici.connect(options[, callback])`

Starts two-way communications with the requested resource using [HTTP CONNECT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT).

Arguments:

* **options** [`ConnectOptions`]
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher]
* **method** `String` - Default: `GET`
* **callback** `(err: Error | null, data: ConnectData | null) => void` (optional)

Returns a promise with the result of the `Dispatcher.connect` method.

`url` may contain pathname. `options` may not contain path.

Calls `options.dispatch.connect(options)`.

See [Dispatcher.connect](docs/api/Dispatcher.md#dispatcherconnect) for more details.

### `undici.upgrade(options[, callback])`

Upgrade to a different protocol. See [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.

Arguments:

* **options** [`UpgradeOptions`]
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher]
* **method** `String` - Default: `GET`
* **callback** `(error: Error | null, data: UpgradeData) => void` (optional)

Returns a promise with the result of the `Dispatcher.upgrade` method.

`url` may contain pathname. `options` may not contain path.

Calls `options.dispatcher.upgrade(options)`.

See [Dispatcher.upgrade](docs/api/Dispatcher.md#clientpipelining) for more details.

## `undici.setGlobalDispatcher(dispatcher)`

* dispatcher `Dispatcher`

Sets the global dispatcher used by global API methods.

## `undici.getGlobalDispatcher()`

Gets the global dispatcher used by global API methods.

Returns: `Dispatcher`

## Specification Compliance

This section documents parts of the HTTP/1.1 specification which Undici does
Expand Down
122 changes: 49 additions & 73 deletions docs/api/Agent.md
Original file line number Diff line number Diff line change
@@ -1,119 +1,95 @@
# Agent

## `new undici.Agent(opts)`
Extends: `undici.Dispatcher`

Arguments:
Agent allow dispatching requests against multiple different origins.

* **factory** - Default: `(origin, opts) => new Pool(origin, opts)`
* // TODO: document rest opts?
Requests are not guaranteed to be dispatched in order of invocation.

Returns: `Agent`
## `new undici.Agent([options])`

Returns a new Agent instance used for dispatching requests.
Arguments:

### `Agent.get(origin)`
* **options** `AgentOptions` (optional)

* origin `string` - A origin to be retrieved from the Agent.
Returns: `Agent`

This method retrieves Client instances from the Agent. If the client does not exist it is automatically added by calling
the `factory` method passed through the `Agent` constructor.
### Parameter: `AgentOptions`

### `Agent.dispatch(options, handlers)`
Extends: [`ClientOptions`](docs/api/Pool.md#parameter-pooloptions)

Dispatches a request.
* **factory** `(origin: URL, opts: Object) => Dispatcher` - Default: `(origin, opts) => new Pool(origin, opts)`
* **maxRedirections** `Integer` - Default: `0`.

This API is expected to evolve through semver-major versions and is less stable than the preceding higher level APIs. It is primarily intended for library developers who implement higher level APIs on top of this.
## Instance Properties

Arguments:
### `Agent.closed`

* **options** `DispatchOptions`
* **handlers** `DispatchHandlers`
Implements [Client.closed](docs/api/Client.md#clientclosed)

Returns: `void`
### `Agent.connected`

#### Parameter: `DispatchOptions`
Implements [Client.connected](docs/api/Client.md#clientconnected)

* **origin** `string | URL`
* **path** `string`
* **method** `string`
* **body** `string | Buffer | Uint8Array | stream.Readable | null` (optional) - Default: `null`
* **headers** `UndiciHeaders` (optional) - Default: `null`
* **idempotent** `boolean` (optional) - Default: `true` if `method` is `'HEAD'` or `'GET'` - Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceeding requests in the pipeline has completed.
* **upgrade** `string | null` (optional) - Default: `method === 'CONNECT' || null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`.
### `Agent.destroyed`

#### Parameter: `DispatchHandlers`
Implements [Client.destroyed](docs/api/Client.md#clientdestroyed)

* **onConnect** `(abort: () => void) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails.
* **onError** `(error: Error) => void` - Invoked when an error has occurred.
* **onUpgrade** `(statusCode: number, headers: string[] | null, socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`.
* **onHeaders** `(statusCode: number, headers: string[] | null, resume: () => void) => boolean` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
* **onData** `(chunk: Buffer) => boolean` - Invoked when response payload data is received. Not required for `upgrade` requests.
* **onComplete** `(trailers: string[] | null) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
### `Agent.pending`

## `agent.close(): Promise`
Implements [Client.pending](docs/api/Client.md#clientpending)

Returns a `Promise.all` operation closing all of the pool instances in the Agent instance. This calls `pool.close` under the hood.
### `Agent.running`

## `agent.destroy(): Promise`
Implements [Client.running](docs/api/Client.md#clientrunning)

Returns a `Promise.all` operation destroying all of the pool instances in the Agent instance. This calls `pool.destroy` under the hood.
### `Agent.size`

## `undici.setGlobalAgent(agent)`
Implements [Client.size](docs/api/Client.md#clientsize)

* agent `Agent`
## Instance Methods

Sets the global agent used by `request`, `pipeline`, and `stream` methods.
The default global agent creates `undici.Pool`s with no max number of
connections.
### `Agent.close([callback])`

The agent must only **implement** the `Agent` API; not necessary extend from it.
Implements [`Dispatcher.close([callback])`](docs/api/Dispatcher.md#clientclose-callback-).

## `undici.getGlobalAgent(agent)`
### `Agent.destroy([error, callback])`

TODO: document
Implements [`Dispatcher.destroy([error, callback])`](docs/api/Dispatcher.md#dispatcher-callback-).

## `undici.request(url[, opts]): Promise`
### `Agent.dispatch(options, handlers: AgentDispatchOptions)`

* url `string | URL | object`
* opts `{ agent: Agent } & client.request.opts`
* // TODO: document maxRedirections?
Implements [`Dispatcher.dispatch(options, handlers)`](docs/api/Dispatcher.md#clientdispatchoptions-handlers).

`url` may contain path. `opts` may not contain path. `opts.method` is `GET` by default.
Calls `pool.request(opts)` on the pool returned from either the globalAgent (see [setGlobalAgent](#undicisetglobalagentagent)) or the agent passed to the `opts` argument.
#### Parameter: `AgentDispatchOptions`

Returns a promise with the result of the `request` method.
Extends: [`DispatchOptions``](docs/api/Dispatcher.md#parameter-dispatchoptions)

## `undici.stream(url, opts, factory): Promise`
* **origin** `string | URL`
* **maxRedirections** `Integer`.

* url `string | URL | object`
* opts `{ agent: Agent } & client.stream.opts`
* factory `client.stream.factory`
* // TODO: document maxRedirections?
Implements [`Dispatcher.destroy([error, callback])`](docs/api/Dispatcher.md#dispatcher-callback-).

`url` may contain path. `opts` may not contain path.
See [client.stream](docs/api/Client.md#clientstreamoptions-factory--callback) for details on the `opts` and `factory` arguments.
Calls `pool.stream(opts, factory)` on the pool returned from either the globalAgent (see [setGlobalAgent](#undicisetglobalagentagent)) or the agent passed to the `opts` argument.
Result is returned in the factory function. See [client.stream](docs/api/Client.md#clientstreamoptions-factory--callback) for more details.
### `Agent.connect(options[, callback])`

## `undici.pipeline(url, opts, handler): Duplex`
See [`Dispatcher.connect(options[, callback])`](docs/api/Dispatcher.md#clientconnectoptions--callback).

### `Agent.dispatch(options, handlers)`

* url `string | URL | object`
* opts `{ agent: Agent } & client.pipeline.opts`
* handler `client.pipeline.handler`
* // TODO: document maxRedirections?
Implements [`Dispatcher.dispatch(options, handlers)`](docs/api/Dispatcher.md#clientdispatchoptions-handlers).

`url` may contain path. `opts` may not contain path.
### `Agent.pipeline(options, handler)`

See [client.pipeline](docs/api/Client.md#clientpipelining) for details on the `opts` and `handler` arguments.
See [`Dispatcher.pipeline(options, handler)`](docs/api/Dispatcher.md#clientpipelineoptions-handler).

Calls `pool.pipeline(opts, factory)` on the pool returned from either the globalAgent (see [setGlobalAgent](#undicisetglobalagentagent)) or the agent passed to the `opts` argument.
### `Agent.request(options[, callback])`

See [client.pipeline](docs/api/Client.md#clientpipelining) for more details.
See [`Dispatcher.request(options [, callback])`](docs/api/Dispatcher.md#clientrequestoptions--callback).

### `undici.connect(options[, callback])`
### `Agent.stream(options, factory[, callback])`

TODO: document
See [`Dispatcher.stream(options, factory[, callback])`](docs/api/Dispatcher.md#clientstreamoptions-factory--callback).

### `undici.upgrade(options[, callback])`
### `Agent.upgrade(options[, callback])`

TODO: document
See [`Dispatcher.upgrade(options[, callback])`](docs/api/Dispatcher.md#clientupgradeoptions-callback).

0 comments on commit 9c04cfa

Please sign in to comment.