Closed ansiwen closed 1 year ago
This looks very reasonable. Unfortunately we don't have good tests yet, but it looks simple enough and if it works for you, we should consider it.
A benchmark of this would be nice to see the impact it has compared to the overhead of using streams (which allows us to represent all modes as bidirectional streaming).
Just a couple of thoughts:
Body.Reader
and Body.Writer
.Connection
module -- in case they can be shared with the server, but also to keep consistent with how the code is organized now.Async
version of this would be nice too. I'm no good at Async
unfortunately.Sorry, completely forgot about this. I will rebase that as soon as I find some time.
I have zero experience with async. But I can try, if it is straightforward.
@ansiwen If you are still thinking about working on this again, this version of unary
for async is the equivalent to your lwt version. I've done some brief testing to check it still works but no profiling yet.
let unary ~handler ~encoded_request write_body read_body =
let payload = Grpc.Message.make encoded_request in
H2.Body.Writer.write_string write_body payload;
H2.Body.Writer.close write_body;
let%bind read_body = read_body in
let request_buffer = Grpc.Buffer.v () in
let on_eof () = () in
let rec on_read buffer ~off ~len =
Grpc.Buffer.copy_from_bigstringaf ~src_off:off ~src:buffer
~dst:request_buffer ~length:len;
H2.Body.Reader.schedule_read read_body ~on_read ~on_eof
in
H2.Body.Reader.schedule_read read_body ~on_read ~on_eof;
handler (Grpc.Message.extract request_buffer)
Thanks @ansiwen and @quernd
This unary implementation does not use streams but simply writes the request out, yields until the response body is available and then copies it into a buffer.
Signed-off-by: Sven Anderson sven@anderson.de