Visitar URL original
feat: add new dispatch compose by metcoder95 · Pull Request #2826 · nodejs/undici · GitHub
Skip to content

feat: add new dispatch compose - #2826

Merged
ronag merged 25 commits into
mainfrom
feat/compose-dispatch
Mar 13, 2024
Merged

ronag merged 25 commits into
mainfrom
feat/compose-dispatch

Conversation

@metcoder95

@metcoder95 metcoder95 commented Feb 23, 2024 •

Copy link
Copy Markdown
Member

This relates to...

Rationale

Changes

Features

Bug Fixes

Breaking Changes and Deprecations

Status

@metcoder95

ghost commented Feb 23, 2024

Copy link
Copy Markdown
Member Author

Next, time to fight with tests and adapt it

ghost left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think just making it available with docs is sufficient here and then we can apply it in next with a revision of my PR.

ghost left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Missing docs and tests

Comment thread lib/interceptor/redirect.js Resolved
Comment thread lib/interceptor/retry.js Resolved
Comment thread lib/interceptor/proxy.js Resolved
Comment thread lib/interceptor/proxy.js Resolved
Comment thread lib/interceptor/proxy.js Resolved
Comment thread lib/interceptor/proxy.js Resolved
Comment thread lib/interceptor/proxy.js Resolved
@ronag

ghost commented Feb 25, 2024

Copy link
Copy Markdown
Member

I would also like us to have some kind of benchmark to this pattern to make sure it doesn't add too much overhead.

Carlos Fuentes and others added 3 commits February 25, 2024 11:30
Co-authored-by: Matteo Collina <hello@matteocollina.com>
@metcoder95

ghost commented Feb 25, 2024

Copy link
Copy Markdown
Member Author

@ronag, did the Proxy worked for you?
I'm trying to add some testing, and it seems it will require several pieces to be changed; especially around the way we handle withe dispatch usage for connect

@ronag

ghost commented Feb 25, 2024 •

Copy link
Copy Markdown
Member

All tests passed. So I think so?

@metcoder95

ghost commented Feb 25, 2024

Copy link
Copy Markdown
Member Author

Well, that's because we I've not pushed the tests for the compose feature; still in my machine and constantly failing, on top I forgot to add the extra dispatcher on the constructor for the Proxy.

But its fine, I just wanted to be sure I had the whole picture. Most likely I'll put back the Agent where it was, and copy/paste and adapt a new copy of the Agent proxy to take into account the new dispatcher arg

@codecov-commenter

ghost commented Feb 28, 2024 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 49.53271% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.48%. Comparing base (0b5a451) to head (620f9bc).
⚠️ Report is 825 commits behind head on main.

Files with missing lines Patch % Lines
lib/interceptor/redirect.js 16.66% 20 Missing ⚠️
lib/interceptor/retry.js 21.05% 15 Missing ⚠️
lib/dispatcher/dispatcher.js 74.46% 12 Missing ⚠️
lib/dispatcher/client.js 46.15% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2826      +/-   ##
==========================================
- Coverage   93.68%   93.48%   -0.20%     
==========================================
  Files          87       89       +2     
  Lines       23973    24102     +129     
==========================================
+ Hits        22458    22531      +73     
- Misses       1515     1571      +56     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread docs/docs/api/Interceptors.md Outdated
Comment on lines +23 to +25
const client = new Client("http://example.com");

client.compose(proxy("http://proxy.com"));

ghost Feb 28, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
const client = new Client("http://example.com");
client.compose(proxy("http://proxy.com"));
const client = new Client("http://example.com").compose(proxy("http://proxy.com"));

Comment thread docs/docs/api/Interceptors.md Outdated
Comment on lines +40 to +42
const client = new Client("http://example.com");

client.compose(redirect({ maxRedirections: 3, throwOnMaxRedirects: true }));

ghost Feb 28, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
const client = new Client("http://example.com");
client.compose(redirect({ maxRedirections: 3, throwOnMaxRedirects: true }));
const client = new Client("http://example.com").compose(redirect({ maxRedirections: 3, throwOnMaxRedirects: true }));

Comment thread docs/docs/api/Interceptors.md Outdated
Comment on lines +57 to +67
const client = new Client("http://example.com");

client.compose(
retry({
maxRetries: 3,
minTimeout: 1000,
maxTimeout: 10000,
timeoutFactor: 2,
retryAfter: true,
})
);

ghost Feb 28, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
const client = new Client("http://example.com");
client.compose(
retry({
maxRetries: 3,
minTimeout: 1000,
maxTimeout: 10000,
timeoutFactor: 2,
retryAfter: true,
})
);
const client = new Client("http://example.com").compose(
retry({
maxRetries: 3,
minTimeout: 1000,
maxTimeout: 10000,
timeoutFactor: 2,
retryAfter: true,
})
);

Comment thread lib/interceptor/proxy.js Outdated
const ProxyAgent = require('../dispatcher/proxy-agent')
const DispatcherBase = require('../dispatcher/dispatcher-base')

class ProxyInterceptor extends DispatcherBase {

ghost Feb 28, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please integrate this inside the ProxyAgent. We shouldn't have special classes for these.

ghost Feb 28, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this should extend Dispatcher, not DispatcherBase.

ghost Feb 28, 2024 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Please integrate this inside the ProxyAgent. We shouldn't have special classes for these.

Sure, let me double-check this part as I'm not totally confident about it, I'd try to first assess if the chain of dispatcher works as expected before trying to port it to the ProxyAgent

Comment thread lib/interceptor/redirect.js Outdated
const Dispatcher = require('../dispatcher/dispatcher-base')
const RedirectHandler = require('../handler/RedirectHandler')

class RedirectDispatcher extends Dispatcher {

ghost Feb 28, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This class is useful as its own export.

ghost Feb 29, 2024

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We can add it as a RedirectAgent

Comment thread docs/docs/api/Interceptors.md Outdated
@@ -0,0 +1,68 @@
# Interceptors

ghost Feb 28, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Generically I don't think we need a special page for the interceptors. They are more confusing than anything else. Let's only have Dispatchers.

Having the use specify (dispatcher) => new MyDispatcher(dispatcher, myOpts) is not a problem for most devs. These helpers only add noise.

Comment thread docs/docs/api/Dispatcher.md Resolved
Comment thread lib/dispatcher/dispatcher.js Outdated

const EventEmitter = require('node:events')

const kDispatcherVersion = Symbol.for('undici.dispatcher.version')

ghost Feb 28, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this the same simbol we use for the global? I think we should use the same.

Comment thread lib/dispatcher/dispatcher.js Resolved
Comment thread lib/interceptor/proxy.js Resolved

ghost left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I slightly disagree with @mcollina. I don't see any point in exposing the dispatcher classes themselves (why would you extend them)? Rather I would prefer exposing curry-able factory methods. That also makes the distinction between composable and non composable dispatcher clearer.

@metcoder95

ghost commented Feb 29, 2024

Copy link
Copy Markdown
Member Author

I slightly disagree with @mcollina. I don't see any point in exposing the dispatcher classes themselves (why would you extend them)? Rather I would prefer exposing curry-able factory methods. That also makes the distinction between composable and non composable dispatcher clearer.

I pushed the change to put both options over the table and chat about which one we would like to follow.
On this one, I agree with @ronag the dispatcher classes made for the interceptors might be better to keep internal, as we are looking to introduce the concept of composable-dispatcher. Otherwise it kind of becomes more like building Agents we already have the concept of

Comment thread index.js Resolved
@ronag

ghost commented Mar 10, 2024

Copy link
Copy Markdown
Member

Actually ProxyAgent might make sense as an interceptor if [kClient] is the outer dispatcher.

Your initial suggestion was doing that somehow, but that will mean break the current ProxyAgent; wdyt if we drop the ProxyInterceptor and we migrate the ProxyAgent to also be an interceptor in the next major?

It doesn't necessarily break it if the interceptor just passed a client factory that return the outer dispatcher?

@metcoder95

ghost commented Mar 10, 2024

Copy link
Copy Markdown
Member Author

Actually ProxyAgent might make sense as an interceptor if [kClient] is the outer dispatcher.

Your initial suggestion was doing that somehow, but that will mean break the current ProxyAgent; wdyt if we drop the ProxyInterceptor and we migrate the ProxyAgent to also be an interceptor in the next major?

It doesn't necessarily break it if the interceptor just passed a client factory that return the outer dispatcher?

Right, that's true; but also we use the client.connect to obtain the socket from the Proxy and pass it down to the connector for doing an upgrade if necessary.
We would need to provide a wrapper around that as well; but its true might be doable within minor

@ronag

ghost commented Mar 11, 2024

Copy link
Copy Markdown
Member

We can also just skip making it an interceptor. I'm fine with that.

@metcoder95

ghost commented Mar 13, 2024

Copy link
Copy Markdown
Member Author

Dropped the proxy interceptor 👍

ghost left a comment

Copy link
Copy Markdown
Member

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 a1ee3ca into main Mar 13, 2024
@metcoder95
metcoder95 deleted the feat/compose-dispatch branch March 13, 2024 20:53
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.

4 participants