-
Notifications
You must be signed in to change notification settings - Fork 420
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
Add scaffolding for client interceptors #986
Add scaffolding for client interceptors #986
Conversation
/// Forwards the response part to the next inbound interceptor in the pipeline, if there is one. | ||
/// | ||
/// - Parameter part: The response part to forward. | ||
/// - Note: This does *not* have to be called from the `EventLoop`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that worthwhile? NIO doesn't bother with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I figured it'd be better to avoid failure since this could be called from off of the event loop, e.g. after deferring to e.g. UI for authentication or something. Perhaps it'd be better to document that it must be called from the event loop and keep the relevant assertions. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think that that's probably better? It's a pretty significant perf win to avoid the check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I gave the pipeline the same treatment: it'll be internal and the inbound side will already be on the event loop. The outbound side will be invoked from the call object, so we can push the check there instead.
if let outbound = self.nextOutbound { | ||
outbound.invokeWrite(part, promise: promise) | ||
} else { | ||
promise?.fail(GRPCStatus(code: .unavailable, message: "The RPC has already completed")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this right? There seems to be some inconsistency between _read
and _write
that I don't fully understand about when the next interceptor might be nil
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So _read
is more like NIOs fireChannelRead
rather than NIOs read
.
What's not implemented here is removing the contexts when the RPC completes, that's when we expect them to be nil
.
Motivation: To support client interceptors we first need to define a few types to work with. Modifications: - Add client request and response parts. - Add the client interceptor protocol. - Add the client interceptor context, which is passed to functions on the interceptor protocol in order to allow implementations to invoke functions on interceptors either side of it in the pipeline. - Add a stubbed out client interceptor pipeline. Result: We have some base types for client side interceptors.
5f81f87
to
3ea34a1
Compare
Motivation: To support client interceptors we first need to define a few types to work with. Modifications: - Add client request and response parts. - Add the client interceptor protocol. - Add the client interceptor context, which is passed to functions on the interceptor protocol in order to allow implementations to invoke functions on interceptors either side of it in the pipeline. - Add a stubbed out client interceptor pipeline. Result: We have some base types for client side interceptors.
Motivation: To support client interceptors we first need to define a few types to work with. Modifications: - Add client request and response parts. - Add the client interceptor protocol. - Add the client interceptor context, which is passed to functions on the interceptor protocol in order to allow implementations to invoke functions on interceptors either side of it in the pipeline. - Add a stubbed out client interceptor pipeline. Result: We have some base types for client side interceptors.
Motivation: To support client interceptors we first need to define a few types to work with. Modifications: - Add client request and response parts. - Add the client interceptor protocol. - Add the client interceptor context, which is passed to functions on the interceptor protocol in order to allow implementations to invoke functions on interceptors either side of it in the pipeline. - Add a stubbed out client interceptor pipeline. Result: We have some base types for client side interceptors.
Motivation:
To support client interceptors we first need to define a few types to
work with.
Modifications:
the interceptor protocol in order to allow implementations to invoke
functions on interceptors either side of it in the pipeline.
Result:
We have some base types for client side interceptors.