Exactly. If you need performance, you'll use Cap'n Proto or FlatBuffer, which use a native binary interface, so you don't need to create and copy objects, you just map them them in from IO.
Exactly. If you need performance, you'll use Cap'n Proto or FlatBuffer, which use a native binary interface, so you don't need to create and copy objects, you just map them them in from IO.
Sure it does. You can implement "streaming" in Cap'n Proto by introducing a callback object, and making one RPC call for each item / chunk in the stream. In Cap'n Proto, "streaming" is just a design pattern, not something that needs to be explicitly built in, because Cap'n Proto is inherently far more expressive than gRPC.
That is, you can define a type like:
interface Stream(T) {
write @0 (item :T);
end @1 (); # signal successful end of stream
}
Then you can define streaming methods like: streamUp @0 (...params...) -> (stream :Stream(T), ...results...)
# Method with client->server stream.
streamDown @0 (...params..., stream :Stream(T)) -> (...results...)
# Method with server->client stream.
Admittedly, this technique has the problem that the application has to do its own flow control -- it has to keep multiple calls in-flight to saturate the connection, but needs to place a cap on the number of calls in order to avoid excess buffering. This is doable, but somewhat inconvenient.So I am actually in the process of extending the implementation to make this logic built-in:
https://github.com/capnproto/capnproto/pull/825
Note that PR doesn't add anything new to the RPC protocol; it just provides helpers to tell the app how many concurrent calls to make.
[0] https://github.com/reactive-streams/reactive-streams-jvm