-
-
Notifications
You must be signed in to change notification settings - Fork 540
Common pattern for reconnections #414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
There is no shortcut in websockets for implementing this. I've heard about this use case before and I think it's valid. I'm unsure whether we can provide a good API -- I would expect user code to do stuff when opening the connection or when it dies and I'm not sure how to handle that? /Cc @RemiCardona |
no progress |
just saw the help wanted tag. |
What needs to do to add this feature? |
For this feature, I would suggest:
|
@heckad I placed a minimal reproducible example here, to start with: https://gist.github.com/pgrandinetti/964747a9f2464e576b8c6725da12c1eb |
I suggest doing like in aio_pika |
…n websockets FAQ and issue 414 python-websockets/websockets#414 Signed-off-by: RomEz10 <[email protected]>
Here is my attempt to talk with websocket server |
An interesting API would be: async for ws in websockets.connect(...):
... Now the question is: should it reconnect only on connection errors? on or all exceptions? This isn't an easy question:
Also, we need exponential backoff to avoid going in a hot loop if the network or the server is down |
Could the behaviour of the reconnection be a parameter passed to the connect method? async for ws in WebSockets.connect(reconnect_policy=websokets.ALWAYS, exponential_backoff=true):
... or something similar? Just putting it out there. I can see a few issues already with what is proposed but hoping something else can build on top of it. |
Just a small remark: re-connecting, and retry connecting are different things
I think that this would translate to always retry if ConnectionClosedError and bailout in all other cases.. I'm not sure if there are cases where the session is valid but the connection was closed with ConnectionClosedOK |
Hello! I have a proposal here: #983. Sorry it took me so long to figure it out. There's a wide variety of situations where connections can fail and require reconnecting. I don't have a good way to reproduce them all. If you have a real life use case and you're able to test this pull request, I would be very interested in your feedback. The idea would be to run the version of websockets from #983, to replace your reconnection system by: async for ws in websockets.connect(...):
... Then you can check if the reconnection works. Errors that trigger reconnections are logged; if you see errors in the logs and the connection is still alive, you're good. Looking forwards to your feedback. Thank you! |
@adriansev: you have a good point; indeed there's a different reasoning for errors opening the connections and errors after it's open. Here's what I ended up doing:
|
I merged the branch but I'm still interested in feedback if you try it :-) |
@aaugustin thank you for your work!! So, just to throw a disclaimer: my view is just from the point of view of the client (and a very dumb client, is a REPL interface to a server, so only one message at a time). So, my comments were from this view, and, as such, i continue to think that retrying the connection when no initial connection was done is pointless (maybe my certificate is wrong, or the wireless is disconnected so, i will wait for an answer from the server when in fact there are re-connecting tryouts in the websocket part). IMHO re-connect would be useful for cases when because of load and network a connection is dropped for very short time. So, for me, my fear is that this would convert to user reports like "i started the client, and nothing happens" as opposed to the often "error was thrown, look in the log" and in the end the problem was of certificate permission, mixed certificate and key (new with old) or other pure ssl problems that will threw errors at connection time. |
Indeed there's no single behavior that will work for everyone if the initial connection fails. I didn't want to get down the path of trying to tell apart fatal errors from temporary errors. At least a stack trace will be displayed so it isn't a silent failure. If you started from scratch today, you could probably use this to make the code that reconnects on pong timeout a bit more elegant. But given that you already wrote it, I'm not seeing much value in refactoring it. |
Well, all depends on "is it worth it?" (in regard to discrimination of types of error and handle them differently) and the range of needs can be quite wide. but, as you say, it throws an exception so it's ok ... |
By "elegant" I meant "can you do everything within a context manager" vs. having a global instance of the websockets client and reinitializing it when it fails. The benefits are those of context managers -- generally they improve the structure of the code and give more clarity to which resource is used where. |
ooh, yeah, that is excluded in my case, as in "technically impossible" : there is not possible to mix async with non-async modules/functions .. so to solve my conundrum, actually i have a thread with the async main loop and a decorator to "un-syncify" the send/receive function (and a few other function that use directly the websocket) |
OK. You need #885, then! |
def run():
try:
asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
except Exception as e:
print(f'WEBSOCKET CONNECTION CLOSED. RESTARTING..', e)
time.sleep(2)
run()
run() |
Hi @aaugustin, I saw that you merged #983 but it is still unclear to me how properly implement the auto-reconnect feature using your library. Thank you! |
Search for "reconnect" in https://websockets.readthedocs.io/en/stable/reference/client.html. |
Thanks @aaugustin! The solution is to do: async for websocket in websockets.connect(...):
try:
...
except websockets.ConnectionClosed:
continue |
In several projects of mines I do something like the following, in order to handle scenario that may happen with connection errors and reconnection attempts:
and I was wondering whether (1) this makes sense at all, and (2) there is any shortcut already provided in
websockets
to what seems quite a recurrent behavior (assuming that is correct!)The text was updated successfully, but these errors were encountered: