I've gotten reasonably far with just doing this myself using my own protoc
plugin, that augments what's already produced by the grpc plugin.

Making the channel an interface does tease out a few other things, that
could give more weight to the "API surface area" argument for *not* exposing
such an interface:

   1. The mechanism for server-side unary RPC handlers to send back custom
   headers and trailers would also have to change. The current mechanism, e.g.
   grpc.SetHeader(...), assumes that there will be a transport.Stream in
   context. For custom dispatch (like might be done from an in-process
   channel), this should instead be a grpc.ServerStream, which could be
   intercepted/wrapped (currently, unary RPC interceptors cannot intercept
   metadata; only stream interceptors can).
   2. The CallOption type needs to be a little less opaque for custom
   channels to interpret/use them. This could be handled by exporting an
   EffectiveCallOptions struct, which is what CallOption instances actually
   operate on (e.g. they mutate fields in the struct).

The above point (about intercepting metadata for unary calls), IMO raises
an argument that unary and streaming RPCs should be unified a little
further. Keeping the generated stubs/handlers for unary calls simple is
great. But the fact that the internal client and server handling also get
forked early on to handle these two cases is a little strange. Not only
does it mean that there are parts of dispatch that must be written twice
(once to handle unary methods and again to handle streaming methods) but
the same is true for user code for users that write interceptors. Ideally,
everything should just use the stream abstraction, all the way up to the
point of dispatching to user's code (server side) / immediately after being
invoked by user's code (client side). FWIW, this is how the Java
implementation works, and I think it is successful.


*----*
*Josh Humphries*
Software Engineer
*j...@fullstory.com <j...@fullstory.com>*

On Tue, Jan 3, 2017 at 7:07 PM, Carl Mastrangelo <notc...@google.com> wrote:

> Hi Josh,
>
> I cc'd a few people who might be able to help.
>
> On Friday, December 16, 2016 at 9:09:59 AM UTC-8, Josh Humphries wrote:
>>
>> I've seen the idea proposed more than once that the generated stubs be
>> backed by an interface -- something along the lines of a channel
>> <https://github.com/grpc/grpc-java/blob/master/core/src/main/java/io/grpc/Channel.java>.
>> Most recently, it was during discussion of client interceptors
>> <https://github.com/grpc/grpc-go/issues/240>. It's also come up as a way
>> of doing in-process dispatch <https://github.com/grpc/grpc-go/issues/247>
>> without having to go through the network stack and (much more importantly)
>> serialization and deserialization.
>>
>> There have been objections to the idea, and I just wanted to understand
>> the rationale behind them. I have a few ideas as to what the arguments for
>> the current approach might be. Is it one or more of these? Or are there
>> other arguments tat I am overlooking or nuance/detail I missed in the
>> bullets below?
>>
>>    1. *Surface Area*. The main argument I can think of is that the API
>>    isn't yet sufficiently mature to lock down the interface now. So exporting
>>    only a single concrete type to be used by stubs makes the API surface area
>>    smaller, allowing more flexibility in changes later. To me, this implies
>>    that introduction of such an interface is an option in the future. (I 
>> don't
>>    particularly agree with this argument since the interface surface area
>>    could have been exposed *instead of* the existing grpc.Invoke and
>>    grpc.NewClientStream methods.)
>>    2. *Overhead*. It could be argued that the level of indirection
>>    introduced by the use of an interface could be too much overhead. I'd
>>    really like to see a benchmark that shows this if this is the case. It
>>    seems hard to imagine that a single interface vtable-dispatch would be
>>    measurable overhead considering what else happens in the course of a call.
>>    (Perhaps my imagination is broke...)
>>    3. *Complexity*. I suppose it might be argued that introducing
>>    another type, such as a channel interface, complicates the library and the
>>    existing flow. I happen to *strongly* disagree with such an argument.
>>    I think the interface could be added in a fairly painless way that would
>>    still support older generated code. This was described in this
>>    document
>>    
>> <https://docs.google.com/document/d/1weUMpVfXO2isThsbHU8_AWTjUetHdoFe6ziW0n5ukVg/edit#>.
>>    But were this part of the objection, I'd like to hear more.
>>
>>
>> For context: I have some ideas I want to build for other kinds of stubs
>> -- like providing special stubs that make batch streaming calls look like
>> just issuing a bunch of unary RPCs, or for making a single bidi-stream
>> conversation resemble a sequence of normal service calls (for some other
>> service) that happen to be pinned to the same stream.
>>
>> All of these currently require* non-trivial code generation* -- either
>> specialized to the use, or I just provide my own interface-based dispatch
>> and build all of these things on top of that. But it feels like a
>> fundamental hole in the existing APIs that I cannot do this already.
>>
>> The Java implementation has a layered architecture with Stubs on top,
>> Transports on the bottom, and Channel in-between. The Go implementation
>> exposes nothing along the lines of channel, instead combining it with the
>> transport into a single clientConn. This is incredibly limiting.
>>
>> *----*
>> *Josh Humphries*
>> Software Engineer
>> *j...@fullstory.com*
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To post to this group, send email to grpc-io@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/CAO78j%2BJgpq%3D7C9bxXYZ7Os%2B-rz9ogoem4UPs-3LrZx_1vH%3DA4Q%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to