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

feat: Add callback context and redirect history. #698

Closed
wants to merge 3 commits into from
Closed

feat: Add callback context and redirect history. #698

wants to merge 3 commits into from

Conversation

ShogunPanda
Copy link
Contributor

This PR concludes #603 by adding support for redirections history in the response.

To guarantee extensibility and encourage other handlers, I chose to introduce in the internal API the concept of context. All three major API methods (request, pipeline and stream) now always return a context in the response. This context is initially just an empty object, but handlers can fill them.

This is what the RedirectHandler current uses.

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
Copy link
Member

ronag commented Apr 8, 2021

Very elegant solution. Good job!

this.handler.context.history = []
}

this.handler.context.history.push(new URL(this.opts.path, this.opts.origin).toString())
Copy link
Member

Choose a reason for hiding this comment

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

What if handler doesn't have context?

Copy link
Member

Choose a reason for hiding this comment

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

Can we pass context similar to how we pass opaque? also make it optional.

Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer if we don't have properties on handlers in terms of user api.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, let me see what I can do. It's also a good idea because it enables custom handlers to be customizable without requiring changes in undici internals.

I'll just clarify in docs that the context object might be modified by undici. Does it sound reasonable?

Copy link
Member

Choose a reason for hiding this comment

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

I'll just clarify in docs that the context object might be modified by undici.

Let's try it and see.

Copy link
Member

Choose a reason for hiding this comment

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

I'll go with user provided object.

Probably also fine. We can start with trying that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why? The redirect handler creates the property on itself and then just calls onContext to give the user access to it.

Because the RedirectHandler is recreated every time (decreasing maxRedirections) when following the chain. I would then store the history in opts and then call onContext. At that point is easier to use the user object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, I have analyzed both solutions.

The first one, passing the context like in opaque is not working as the opts are lost in the API handler (since we destructure there). Saving the context there is not different from what I'm doing now and it complicates the external API so I gave up on that.

The onContext approach instead has the issue that if the chain is interrupted (if maxRedirections reaches 0 and 3xx is still returned) is not called at all as it is inside RedirectHandler and not inside the Agent.

I also tried to call onContext expecting the bottom handler to return an object to modify. But this implies saving the context in the bottom handler which is what I'm doing at the moment.

I also tried to mix the approaches, no luck.

I therefore think we should keep the current implementation, unless you have better idea.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for putting the effort into considering both approaches. I'll also have a go at this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, keep me posted then. In the meanwhile I'll just send one more commit that checks that the handler has a context before attempting to set it.

@ronag ronag force-pushed the main branch 2 times, most recently from b4b20c6 to 6bee407 Compare April 8, 2021 08:34
@ronag ronag modified the milestone: 4.0 Apr 8, 2021
Copy link
Member

@ronag ronag left a comment

Choose a reason for hiding this comment

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

Changes look good. I would however like to give this more thought. It's easy to add API's but more difficult to modify.

@ronag
Copy link
Member

ronag commented Apr 8, 2021

Maybe we should land this with docs and typedefs after @Ethan-Arrowood has done his iteration. I kind of told him that there would be no further API changes 😄 .

@ronag
Copy link
Member

ronag commented Apr 9, 2021

What about an additional optional context arg passed to onConnect(abort, context)?

@ShogunPanda
Copy link
Contributor Author

How is it different from the onContext approach above? The problem is still what I highlighted above: on the last redirect the RedirectHandler is not used at all so it cannot finalize the history.

@ShogunPanda
Copy link
Contributor Author

@ronag Any update on this? How are we moving forward?

@ronag
Copy link
Member

ronag commented Apr 13, 2021

@ronag Any update on this? How are we moving forward?

I haven't had time yet to dig into this. Hopefully more time on Thursday.

@ronag
Copy link
Member

ronag commented Apr 19, 2021

I looked into it last thursday but didn't have enough time, will try again this thursday

@ronag
Copy link
Member

ronag commented Apr 24, 2021

Closing in favor of #769 which is a continuation.

@ronag ronag closed this Apr 24, 2021
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

5 participants