Re-architecture for Stream style interceptors (WIP) #86
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
WIP
Large refactor of
handler.go
to convert the protocol interfaces to act on headers, messages, trailers and errors. From this we can divide the stream into the client/server and implement interceptors that affect control flow. This makes it possible to implement custom backends and adopt connects interceptor library to run through vanguard. Another use case is to gain direct access to gRPC server methods and do direct dispatch, avoiding the re-encoding of messages and replace gRPC's ServeHTTP method entirely.Protocol Interface
The private Client protocol interface is now:
Errors are handled by the client protocol, server's raise errors from their trailer messages. The flow is simplified by having some protocols be stateful avoiding needing to share data in
*operation
.Codecs and compressors are set by the protocols. This allows for better optimization on detecting when it's required to convert protocols. For example, REST protocol sets a codec with the name
rest-json
which is compared to the server's codec and only converted if different. Setting compressors allow protocols to also set full stream compression. So REST HttpBody requests can now compress/decompress streams of data.Buffers
Message conversion is done using the buffering techniques proposed here: #29
All messages are currently buffered, a regression, but streaming can easily be added as a message stage to avoid full buffering. From benchmarks it looks like the impact is minimal, unmarshalling and compressing are only invoked if necessary already. Large messages might make it worthwhile.
Interceptor
Interceptor could look like this
Stream
interface. For example, on creation headers are decoded from the client providingReceiveHeaders
. WhenReceiveMessage(..)
is invoked the client prepares the message buffer and then decodes into the message. OnSendMessage(..)
client prepares message and then marshals and writes the response.Testing
All current
TestMux_
tests are passing. Some http error code passthrough is WIP. Also need to re-add content-length and max message size testing.The work to split up the message control from the operation will make it much easier to test individual parts.
Performance
Current benchmarks show a 15% throughput increase with less memory overhead and lower allocations. The
PassThrough
benchmark is the only one slower, as this optimization isn't yet added so it's comparing doing nothing vs going through the full transcoder.