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

L12: C# Interceptors Proposal #38

Merged
merged 8 commits into from
Jun 7, 2018
Merged

L12: C# Interceptors Proposal #38

merged 8 commits into from
Jun 7, 2018

Conversation

mehrdada
Copy link
Member

@mehrdada mehrdada commented Sep 19, 2017

@mehrdada
Copy link
Member Author

@jtattermusch What do you think about merging the ServerInterceptor and ClientInterceptor base classes into one, as there is no abstract method in them, if someone wants to implement only one side, they can, and this way they could share logic more easily if there is an interceptor operating on both sides? I am conflicted on this myself, so your PoV would be appreciated.

@mehrdada mehrdada changed the title C# Interceptors Proposal L12: C# Interceptors Proposal Sep 19, 2017
underlying `CallInvoker` handler for the final interceptor in the chain:

```csharp
TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request, Func<Method<TRequest, TResponse>, string, CallOptions, TRequest, TResponse> next);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: add line wraps for better readability.

proposal suggests adding an `Items` dictionary to `ServerCallContext` to hold
arbitrary state.

## Rationale
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we would benefit from one of:

  1. extra section with main use cases and examples.
  2. examples directly in the implementation PR (as unit tests or in Grpc.Examples project).

In my experience example snippets is where potential flaws of a new API are the easiest to spot and without it reasoning about the API pros and cons becomes very abstract.


In the general case, the interceptors are not obligated to invoke `next` once.
They might choose to not continue with the call chain and terminate it
immediately by returning their own desired return value, or potentially call
Copy link
Contributor

Choose a reason for hiding this comment

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

I think allowing shortcircuiting the call and retries are an interesting use case, but I'd like to see an example of those to make sure such scenarios really work.

code when certain events happen in asynchronous and streaming calls. These
helper static functions are the only reason this facility could not have been
implemented by an external library: they require access to the internal
constructors of `AsyncUnaryCall<TResponse>`,
Copy link
Contributor

Choose a reason for hiding this comment

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

FYI we've actually been thinking of making those constructors public (they're useful for testing as well).


Since support for this handler substitution was needed from the
`ServerServiceDefinition` class itself, a general internal method
`SubstituteHandlers` is added to actually apply the mapping given the wrapping
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: if it's an internal method, it's probably irrelevant for the public API discussion here - it's purely a question of implementation.


## Rationale

The design goals where flexibility, decoupling and non-disruption to existing
Copy link
Contributor

Choose a reason for hiding this comment

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

one design goal worth explicitly calling out is to not break the existing API surface.

- Unify `ClientInterceptor` and `ServerInterceptor` classes into
  one `Interceptor` base class, so that implementing a single
  class to serve on both sides becomes possible.

- Update the signature of the client interceptor hooks, taking
  a context object instead of the contextual data in-line. Also,
  rename the `next` delegate to `continuation` for clarity.

- Update the server-side interceptor machinery to reflect the
  new design, which is able to intercept the call before reading
  the first request and express interest in further interception
  if necessary.

- Formatting and clarifications.
@mehrdada
Copy link
Member Author

mehrdada commented Oct 17, 2017

@chwarr please take a look at the updated proposal (and the PR)

AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(
ClientInterceptorContext<TRequest, TResponse> context,
AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation)
```
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: looks like premature termination of the code block here.

@chwarr
Copy link
Contributor

chwarr commented Oct 19, 2017

Looking at my schedule, I'm unlikely to have time to look at the implementation PR until next week at the earliest, and perhaps not even then. Please do not block on me.

@hsaliak
Copy link
Contributor

hsaliak commented Feb 2, 2018

@mehrdada @jtattermusch looks like this one is ready to be merged. Could you please do so?

@mehrdada
Copy link
Member Author

mehrdada commented Feb 2, 2018

Please do not merge this. There are some learnings from Python that I would like to apply on this. It is at the top of my priority list after P0 resolution.

@jtattermusch
Copy link
Contributor

@mehrdada any progress?

@mr-at0s
Copy link

mr-at0s commented Jun 1, 2018

Friendly ping: @mehrdada Any progress on this? :)
I added this to the community meeting agenda. http://bit.ly/grpcmeetings

@jtattermusch
Copy link
Contributor

@mehrdada the interceptors have been available in c# for a while, we should get the proposal finalized and merged.

@mehrdada
Copy link
Member Author

mehrdada commented Jun 7, 2018

@jtattermusch Done. PTAL and add a commit to change the status to Accepted if satisfactory.

@mehrdada
Copy link
Member Author

mehrdada commented Jun 7, 2018

@mr-at0s just uploaded the polished prose and @jtattermusch should be able to merge

invocations are separate and both need to be implemented and overriding one
does not automatically apply to the other.

Of the aformentioned methods, the ones that intercpet request-unary RPCs take
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: intercpe

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@jtattermusch jtattermusch left a comment

Choose a reason for hiding this comment

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

LGTM.

@mehrdada mehrdada merged commit 2beffc2 into grpc:master Jun 7, 2018
@mehrdada mehrdada deleted the csharp_interceptors branch June 7, 2018 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants