Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Unify Client, Pool & Agent #620

Merged
merged 6 commits into from
Mar 31, 2021
Merged

refactor: Unify Client, Pool & Agent #620

merged 6 commits into from
Mar 31, 2021

Conversation

ronag
Copy link
Member

@ronag ronag commented Mar 25, 2021

  • Unifies Client, Pool and Agent under a single interface.
  • Removes Agent.get (in favor of extra args to client connect/disconnect).
  • Removes Client/Pool.busy in favor of return value on dispatch. (I'm not 100% sure this is possible, but I think so).
  • Makes connect/disconnect emit an array of entire connect/disconnect chain for introspection.
  • Makes 'drain' emit origin as first argument.
  • Makes Agent a client with all the api methods (request, stream etc...) on the prototype and same events as Client.

So Agent, Pool and Client all implement the same interface and could be used interchangeably.

Fixes:

#610
#616
#612

@ronag ronag added this to the 4.0 milestone Mar 25, 2021
@ronag ronag requested a review from mcollina March 25, 2021 11:12
@ronag ronag requested a review from dnlup March 25, 2021 11:46
@ronag

This comment has been minimized.

@ronag ronag force-pushed the agent-client branch 5 times, most recently from 484d0fc to 4260bdf Compare March 25, 2021 13:46
@ronag
Copy link
Member Author

ronag commented Mar 25, 2021

This needs more work but I'd like to have some initial feedback before spending more time.

@ronag ronag changed the title refactor: Client.clients & Agent is a Client. refactor: Unify Client, Pool & Agent Mar 25, 2021
@ronag
Copy link
Member Author

ronag commented Mar 25, 2021

@ShogunPanda

@ronag
Copy link
Member Author

ronag commented Mar 25, 2021

The Client interface basically becomes:

interface Client implements EventEmitter {
  dispatch(opts, handler): Boolean
  destroy(err, callback)
  'drain' (origin, clients)
  'connect' (origin, clients)
  'disconnect' (origin, clients, err)

  // These are not really necessary for the required API
  close(callback)
  closed: Boolean
  destroyed: Boolean
  connected: Integer
  size: Integer
  running: Integer
  pending: Integer,
}

@mcollina
Copy link
Member

Huge +1 to this.

lib/agent.js Outdated Show resolved Hide resolved
lib/pool.js Outdated Show resolved Hide resolved
lib/agent.js Show resolved Hide resolved
@ShogunPanda
Copy link
Contributor

+1 for me as well. I'd just wait for #603 (with my improved coverage which is coming up) to land so we can rely on tests.

@ronag ronag mentioned this pull request Mar 25, 2021
@ronag
Copy link
Member Author

ronag commented Mar 25, 2021

@jonnydgreen FYI, WIP.

@jonnydgreen
Copy link
Contributor

Looks awesome, thanks for keeping me in the loop :)

@ronag ronag force-pushed the agent-client branch 3 times, most recently from 491796b to 68b44e6 Compare March 27, 2021 18:18
@ronag ronag mentioned this pull request Mar 27, 2021
@ronag ronag changed the base branch from main to minor-fixes March 27, 2021 18:25
@ronag ronag force-pushed the agent-client branch 4 times, most recently from e66d8b2 to f915b49 Compare March 27, 2021 18:31
@ronag ronag force-pushed the agent-client branch 2 times, most recently from 86d1cd9 to d88585d Compare March 30, 2021 08:19
@ShogunPanda
Copy link
Contributor

+100 from me. I really like the new API! Go for it!

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are benchmarks impacted by this change?

lib/agent.js Show resolved Hide resolved
lib/agent.js Show resolved Hide resolved
lib/agent.js Outdated
.on('disconnect', this[kOnDisconnect])
.on('drain', this[kOnDrain])

this[kClients].set(opts.origin, new WeakRef(client))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don’t cleanup. It’s a minor mem leak. I personally think it’s fine but would like some more opinions.

Is this what is described in #631? It should only be a temporary leak from my understanding of it.

test/agent.js Show resolved Hide resolved
lib/agent.js Outdated Show resolved Hide resolved
lib/dispatcher.js Show resolved Hide resolved
test/agent.js Outdated Show resolved Hide resolved
test/agent.js Outdated Show resolved Hide resolved
@mcollina
Copy link
Member

@jonnydgreen do you think this API would be ok for you to support in #587

@jonnydgreen
Copy link
Contributor

jonnydgreen commented Mar 30, 2021

@mcollina yep, definitely! Looking at the code, I don't see any major problems when it comes to adding mocking support. If anything, I think it will make everything a lot cleaner to implement and opens up a lot of additional functionality in the mocking support as I can use setGlobalDispatcher for MockClient and MockPool as well :)

@ronag
Copy link
Member Author

ronag commented Mar 30, 2021

Are benchmarks impacted by this change?

We have the benchmark CI 😄 .

branch:

[1] http - no agent  x 653 ops/sec ±2.08% (78 runs sampled)
[1] http - keepalive x 746 ops/sec ±1.86% (72 runs sampled)
[1] http - keepalive - multiple sockets x 4,953 ops/sec ±2.91% (76 runs sampled)
[1] undici - pipeline x 5,311 ops/sec ±4.38% (74 runs sampled)
[1] undici - request x 6,034 ops/sec ±2.48% (75 runs sampled)
[1] undici - pool - request - multiple sockets x 6,324 ops/sec ±2.70% (78 runs sampled)
[1] undici - stream x 6,667 ops/sec ±2.34% (80 runs sampled)
[1] undici - dispatch x 6,732 ops/sec ±2.31% (78 runs sampled)
[1] undici - noop x 6,367 ops/sec ±1.61% (76 runs sampled)

master:

[1] http - no agent  x 679 ops/sec ±1.50% (79 runs sampled)
[1] http - keepalive x 727 ops/sec ±1.34% (73 runs sampled)
[1] http - keepalive - multiple sockets x 4,236 ops/sec ±3.03% (80 runs sampled)
[1] undici - pipeline x 5,056 ops/sec ±3.70% (81 runs sampled)
[1] undici - request x 5,846 ops/sec ±1.78% (80 runs sampled)
[1] undici - pool - request - multiple sockets x 5,882 ops/sec ±1.39% (82 runs sampled)
[1] undici - stream x 6,087 ops/sec ±1.69% (79 runs sampled)
[1] undici - dispatch x 6,266 ops/sec ±1.48% (81 runs sampled)
[1] undici - noop x 6,459 ops/sec ±0.91% (81 runs sampled)

Seems faster if anything.

@ronag
Copy link
Member Author

ronag commented Mar 30, 2021

I will run more in depth benchmarks on the same EPYC machine the README results come from before release.

Copy link
Collaborator

@Ethan-Arrowood Ethan-Arrowood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks great. really happy to see the core API refactor for easier client instantiations

lib/dispatcher.js Show resolved Hide resolved
lib/dispatcher.js Show resolved Hide resolved
lib/pool.js Show resolved Hide resolved
@mcollina
Copy link
Member

What would entail in solving the memory leak? Can't we do the connect/disconnect solution that we used in main?

@ronag
Copy link
Member Author

ronag commented Mar 31, 2021

What would entail in solving the memory leak? Can't we do the connect/disconnect solution that we used in main?

I don’t like/trust that solution but I can look into it again for node 12.

@dnlup
Copy link
Contributor

dnlup commented Mar 31, 2021

What would entail in solving the memory leak? Can't we do the connect/disconnect solution that we used in main?

I don’t like/trust that solution but I can look into it again for node 12.

Not sure if feasible, but we could keep the FinlizationRegistry interface implemented here, and use the connect/disconnect events to trigger the kFinalizer.

@mcollina
Copy link
Member

What would entail in solving the memory leak? Can't we do the connect/disconnect solution that we used in main?

I don’t like/trust that solution but I can look into it again for node 12.

Not sure if feasible, but we could keep the FinlizationRegistry interface implemented here, and use the connect/disconnect events to trigger the kFinalizer.

Only on Node v12. It's definitely better than leaking.

@ronag
Copy link
Member Author

ronag commented Mar 31, 2021

@mcollina @dnlup fixed, PTAL

@dnlup your idea is very elegant, I like it!

lib/agent.js Show resolved Hide resolved
@ronag ronag requested a review from mcollina March 31, 2021 11:14
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ronag ronag merged commit 9c04cfa into main Mar 31, 2021
@Uzlopak Uzlopak deleted the agent-client branch February 21, 2024 12:39
crysmags pushed a commit to crysmags/undici that referenced this pull request Feb 27, 2024
* refactor: Client.clients & Agent is a Client.

Refs: nodejs#616

* fixup: rename clientt to dispatcher

* fixup: keep promise chain

* fixup

* fixup

* fixup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants