-
Notifications
You must be signed in to change notification settings - Fork 4k
In-process transport #640
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
In-process transport #640
Conversation
8ee08e8 to
e224066
Compare
|
@ejona86, I think this looks pretty good. I started going through reviewing each commit, but maybe that's premature? I'm a little concerned about having to register them by name into a static set. Code that wants to start multiple servers in the same JVM would have to generate unique names. Do we need the client and server to be so de-coupled? From my perspective, I'd prefer ditch the static registry and require callers to supply an |
|
@jhump, I wasn't finding it necessary for you to do a full review (but if you do, I value it!). I was mainly interested in how you felt about high-level approach, performance, and construction details. Basically, does it help you and what do you dislike about it? I think the registry-variety will be needed and useful. With it we can communicate to disparate parts of code what to connect to. All the load balancing and naming discussions have led to "us" (but not yet Java) moving to a URI-based mechanism of naming. With it, we could conceivably have a "inprocess:///registeredName" address and have a utility to auto-select the in-process transport. I'm completely fine with having an anonymous server and passing it to the channel builder to bind. I considered doing it initially, but figured it would be easy to add. It would still need to be shutdown manually, and getting rid of that without using a finalizer is tricky. I'm working on a registry-free version now. |
|
Hmm... registry-free is a bit tricky since we don't have a reference to the server transport. We could have some object that you pass to the builder that is given knowledge of the server transport and then lets you construct channels. Seems like it has all the properties that you want, but feels weak. We could have the registry and allow auto-generated names or use objects as keys. "new Object()" is pretty easy to make sure you have a unique key. Depending on how we did the auto-generated name, it might help to implement #72. These don't seem to be hard to implement, but it does seem hard to choose one. I'm going to continue thinking about it. |
|
@jhump, sorry about my initial message for this PR. I later realized why the confusion, because it seemed "The commits are split up for easier reviewing" was directed toward you. (I've since put a HR separator.) I'm glad you stopped when things seemed strange. |
|
This looks like a great start, and the performance test results do look very compelling. I'm still a little skeptical of having to serialize and deserialize every message. I bet the features of the transport could be used without needing serialization -- like if (Related, but not directly pertinent: I noticed that there is still no safety on the serializers -- for example, a client Regarding the registry, I'm not sure I understand why making it registry-free is tricky. If you make |
288517e to
7b7e927
Compare
|
@jhump, we don't actually serialize/deserialize every message unless it appears we have to. That was the point of c6e4a82. The Concerning the serialization checking: I'm less concerned about proto vs JSON and more concerned of message types matching. Getting the message types wrong seems much more likely than the encoding, and there is no current defense for that. The proto vs JSON seems more like a special case. As of today, no implementation is sending the The suggestion about making |
|
@ejona86 Let's separate out the first 4 commits. They LGTM after a couple of comments are addressed. |
|
@ejona86 Just a few comments on the in-process transport. Looks great! |
|
@ejona86, my blunder. Sorry for the noise and thanks for linking to that commit. For some reason, I stopped at the "implement InProcessTransport" commit and didn't look closely at the subsequent commit messages. The lack of serialization does explain why the JMH benchmark results are so good! In that case, this is perfect! I still like the idea of not needing to register and lookup in-process server instances, but that's a minor point that's certainly not a blocker. Thanks! |
|
@jhump, I don't really blame you, there was a lot to look through and there were multiple pieces I could have communicated better. It is actually unfortunate that the serialization circumvention is already done, as otherwise the JMH benchmark would get even better :-P I'll be quickly trying to add the construction pattern that avoids the registry, because I would actually like that too. If it starts slowing me down too much I'll skip it for now; I do agree it doesn't seem a blocker, and seems it should be same difficulty to add now or later. |
7a6c90b to
bab0843
Compare
|
@nmittler, I've pushed the 4 commits that were just prepwork for the inprocess transport. I've rebased this PR, but left my fixups separate so that you don't have to worry about me changing commits you already reviewed. |
|
@ejona86 LGTM ... we can address further changes (e.g. no registry) with follow-on PRs as needed. |
Resolves grpc#518
In-memory transport provides back the same input stream that was provided, so if we notice our own object simply avoid serializing. DeferredProtoInputStream is made package-private because 1) it doesn't seem we need it to be public and 2) the change depends on it being package-private so the constructor can be changed.
The only benchmark method measures latency of a unary call in an unloaded environment.
924c457 to
bf53a0e
Compare
|
Submitted changes without "no registry" support, since @nmittler reviewed before I got them done. The will be done in a follow-up. |
@jhump, does this approach work for you? I did end up coming up with a fix for the type-safety issue by checking that the original serializer of the protobuf is the same as the deserializer.
The commits are split up for easier reviewing. The commit messages do have some useful notes. The JMH benchmark was added to be able to compare the performance to the other transports.
I'm not actually sure which project we want the transport in. I put it in core for now, but I am very okay with moving it elsewhere. I would want it reasonably accessible, as things like the stubs should probably use it for their tests.
The transport is fully-featured with full support for flow control and running multiple instances. With this transport, we could actually test client-side load balancing and other higher-level features without mocking and without bringing in large dependencies. That will lead to more reliable, maintainable, readable, and writable tests.
The DEADLINE_EXCEEDED change was necessary because the ServerImpl reliably starts its deadline timer before the ChannelImpl does (because ChannelImpl starts the timer after the transport has created the call). We needed the fix already and I had already discussed with gRPC C folks about the need for it, but it was a prerequisite to get tests passing with this transport while also making the transport act like a real HTTP/2 transport.
The benchmark tested the unloaded latency of the various transports:
Resolves #518