(I'd have talked sooner, but got out of my routine so wasn't watching.)
I do think #8398 is the right one to watch. ericgribkoff has been messing with this more recently.
weatherhead joined the channel
npgm has quit
MasterGberry has quit
grepory joined the channel
MasterGberry joined the channel
noonien joined the channel
rav3nn joined the channel
rav3nn has quit
npgm joined the channel
Nick_64_ joined the channel
Nick_64_
Can grpc have the server send ssomething to a client without a request from it (Start from the server?
Or keep a stream from the server to the client open for a long time and then have the client "Hook" a function for each element received in a non-blocking way
And, is it possible for the server to keep data/context for a connection through many messages? Like a login/auth
Sorry if these questions are stupid, I'm not sure if grpc is what I'm looking for yet
|Pixel|
so, no, the server can't send anything to the client without an initial request, but what you said next is true: you can do long lasting streaming calls
ejona
Nick_64_: The client must always start with a request. The client could start an RPC and leave it open for a long time. The "hook"ing you'd make yourself. Non-blocking depends on the language.
But could i make it so it ends up working as if the server was sending stuff?
Like, can i trigger some code whenever the open stream gets data in the client?
Like a hook function or something
Instead of using ->Next() in cpp which seems to be blocking
ejona
When the open stream receives data, you could choose what to do with it.
Nick_64_
Say I have a game. I want to recieve messages from a server. Could i make it so i connect to the server, send a request, keep an open stream and a function (Or something equivalent) is called every time the server sends something through that stream?
ejona
For the last question, no I strongly discourage doing connection-based state. Lots of things break it. Instead, I'd suggest the client send the information every request and use a cache or similar on server-side.
Nick_64_: in C++, yes. That'd be the async API (vs blocking). |Pixel| would be able to point you to details.
Nick_64_
I saw an async example for the route thing in cpp
|Pixel| ducks
ejona mmmm
But iirc it did something like while(stream->Next()) to read from the result/response stream
And that Next seemed to be blocking
|Pixel|
so
there's often confusion on the notion of async and whatnot with regards to C++
gRPC is its own event loop
so while you can send multiple requests in parallel
and be able to get their answers asynchonously from each other
you are still going to go inside grpc's event loop to process them
Nick_64_
Mhm
|Pixel|
if you use the completion queue mechanism, without any deadline, yes, you will wait forever until something happens there
Nick_64_
Is there something to check if theres unread/new data in a stream?
So i could just run that in my main loop
|Pixel|
if you are writing a video game however, and wants to process other things while maxing out the CPU, then on each "frame" of your game, you can call into grpc's completion queue with a deadline of 0
Nick_64_
I mean I'd have a "message sent by the server" which I wouldnt need anywhere, it would just trigger some action client-side
|Pixel|
making sure that you will return immediately whatever happens
check greeter_async_client.cc
the change in this one code for the mode I am talking about would be
Nick_64_
rpc->Finish(&reply, &status, (void*)1);
Changing that to a 0?
|Pixel|
no :)
that's your tag; typically you want a pointer here
this line:
GPR_ASSERT(cq.Next(&got_tag, &ok));
blocks
and is the main event loop / dispatcher
you want to change it to call AsyncNext instead
with a deadline of 0
so that it returns immediately
Nick_64_
Oh right makes sense, completionQueue.Next
|Pixel|
basically, when you call Finish, you pass a "tag", here we say 1, but usually people would create an object in memory
and pass the pointer of that object to Finish for context
then when the completion queue returns with a tag, cast that tag back to a pointer of that type of object to continue the context
internally the type for "tag" is a uintptr, so it's guaranteed to fit any sort of pointer safely
(well, most sorts of pointers...)
Nick_64_
So, if i called std::unique_ptr<ClientReader<MessageType> >->Read(&item) with a stream response using AsyncNext
It would not return true until the server sent something, and the main event loop wouldnt block
|Pixel|
along these lines, yes :)
Nick_64_
Thanks a lot, I think I can use grpc for what i wanted :)