One more `wire` + `grpc` question. If I have a ser...
# squarelibraries
One more
question. If I have a service like this
Copy code
rpc getItemsStream(ItemRequest) returns (stream ItemResponse) {}
How do I send the initial request? Wire generates the implementation of GrpcStreamingCall which has 2 channels. Do I understand correctly that I must send initial request using a
? My issue posted above seems to be caused by no request body being sent. Sending it to the channel doesn't help, maybe I must do it otherwise? Stub implementation generated by
library has this explicitly:
fun getItemsStream(request: ItemsRequest): Flow<Response>
, but
generates function with no params in this case.
OK. I started doing this:
Copy code
And now things went alive! I can see in server logs that events are being sent from server to client. If this is the right way to do this, you really should document this, wasted a lot of time of this "obvious" stuff 🙂
But now I have another issue: client does not receive those streaming messages. I can see this event from OkHttp
Copy code
okhttp.OkHttpClient  I  [53 ms] responseBodyStart
and then silence. Am I again not consuming them right? I call
on the client.
If you close the
it closes the whole connection. You wanna send request on one thread, and read the responses on another. If you close any of them, the connection dies.
Hmm. Without closing, server doesn't receive request body at all. Wait, does this mean that if I'm doing this:
Copy code
GlobalScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
  val (send, receive) = service.someStreamingCall().execute()
  for (resp in receive) { println(resp) }
...then I'm effectively blocking a thread? Because I do it like above and a) either send doesn't work, no request body goes out, times out b) adding 'close()' after send actually causes server to receive the request, but then connection is closed This would explain things, but then... if I remove this
it still doesn't send the body. Eeeh. I hope I'll figure this out,
is soooo much simpler than "native" grpc stuff.
you should close the send channel
@Benoit Quenaudon we should confirm that closing the send channel doesn’t close the whole connection! That’s valid for unidirectional streaming
I'm sorry, ok. Hmm I'll check
It actually looks 👌: it doesn't close the connection: after doing
I can see that server keeps sending me outbound data requests in the stream. But for some reason I dont receive them in the receive channel, okhttp's event listener reports
and nothing after that, I guess no body is being read. wire's sample has only bi-directional streaming example, so I'm not sure if i'm doing everything right, but I do it like in the snippet I posted above.
Also maybe related: after I
, while connection is not closed, but logging interceptor prints
<--- 200 OK
, so does this mean that the streaming response is considered to be done/finished? Maybe that's why I don't receive anything in the receive channel? (streaming responses still continue to 'tick' in the server logs)
I'll try to write a test
Yep, I saw them too, forgot to mention. Still, I don't get anything in the receive channel for some reason. Server does send the stream, every 2 seconds, see it in server logs, but receive channel is empty on my side. Do you use unidirectional streaming in cash app (or wherever?). Maybe this issue manifests only on "live" connections, in non-test environment.
We have duplex working in cash app
But we don't close the request until the end
I'd try to reproduce my problem on wire's "whiteboard" sample, to come up with the minimal example, but there's that issue with MainActivity not available in the apk (which I still didn't wrap my head around 🙂 )
Yeah the sample is broken right now. Maybe try to write a test in grpc client tests with the same schema that you have and see if the test passes
ok! I'll report if I'll find anything simply-reproducable.
Curiously, I see something similar, receive() is successful once, but upon second call it never returns. When I try stepping into the receive call android studio misbehaves and I usually crash straight up. So I'm guessing I'm passing bad data in or something else isn't setup correctly, which is what I'm investigating.
Also, that test in GrpcClientTest can't be being called (or can it?). It's using
which is error deprecated for
. Maybe I'm missing something?
Oh, and I forgot to mention, if I use
in my loop to get data, I don't have to
the sendChannel in order to receive that one message. But if I try to use the
for (update in receiveUpdateChannel)
stuff, it only receives that one message if I do
the channel.
I suspect there's something weird with concurrency going on.