grpc / grpc-web

gRPC for Web Clients
https://grpc.io
Apache License 2.0
8.45k stars 760 forks source link

Client reconnection to long-running poll #1398

Closed dbischof90 closed 4 months ago

dbischof90 commented 5 months ago

Hi,

I'm currently evaluating gRPC as a potential protocol and would like to clarify a few things. One of them is the following scenario:

A client A and a Server B estaiblish a connection, A calls B with a long-running operation (minutes, maybe even hours, somewhat impossible to say but not short) which I'll call f. Now A closes the connection (application shutdown, connection loss, all that jazz). Is it possible to reconnect to the RPC query sent before the disconnect? I know that the client has a reconnection policy in case the server goes away but I could not find much information about this specific scenario.

I currently implement this scenario via a method-specific cache, e.g. some methods are expected to run long, I have essentially a dictionary with arguments and results and the RPC call essentially waits until a separate thread has written a result into this dictionary and returns it, after the first return the entry in the dictionary is cleared again. I was wondering if there is something built-in already which would cover this, as you can imagine, this is not necessarily the most scalable solution and has several short-comings (e.g. what happens if two clients issue the same call to the server and then just one gets a return and so on) and before I create a frankenstein-ish solution I thought I check in and ask šŸ˜„

sampajano commented 4 months ago

Hi, thanks for the question!

Is it possible to reconnect to the RPC query sent before the disconnect? I know that the client has a reconnection policy in case the server goes away but I could not find much information about this specific scenario.

I guess to achieve that, you'd first have to make sure the request lands on the same server B, not B' (assuming you hav more than 1 server). For that I would imagine it require some "stickiness" setup from your server side, potentially achievable via cookies and some other means (e.g. sharding by user ID). (This is outside of the concern of the grpc-web library.)

I currently implement this scenario via a method-specific cache, e.g. some methods are expected to run long, I have essentially a dictionary with arguments and results and the RPC call essentially waits until a separate thread has written a result into this dictionary and returns it, after the first return the entry in the dictionary is cleared again.

Yeah i mean this sounds like a decent solution given it doesn't raise a memory concern.

I was wondering if there is something built-in already which would cover this, as you can imagine, this is not necessarily the most scalable solution and has several short-comings (e.g. what happens if two clients issue the same call to the server and then just one gets a return and so on) and before I create a frankenstein-ish solution I thought I check in and ask šŸ˜„

I think you're essentially asking for a state-full RPC support. Which i do not believe is support by gRPC natively.

For achieving that more reliably, i recommend that you implement some kind of "continuation token" which is returned to the client along with server results. So that when the client reconnect, it can provide this "token" and server would know where to resume from.

I hope that's somewhat helpful but sorry there's no native support from gRPC on this particular feature. I'll close this issue for now. But Good luck to your solution! :)