From 621255027d5c0a5046d95cef8e80e448ef2ca991 Mon Sep 17 00:00:00 2001 From: Georg Lukas Date: Sun, 29 Mar 2020 14:16:11 +0200 Subject: [PATCH] Reset reconnect delay on manual reconnect, add delay event This is just a hotfix workaround for an underlying problem. The `_connect_routine` code is "blocking" (in an async way) for `connect_loop_wait` seconds, so that a fresh-started manual reconnect will be silenty delayed. This code does the following changes: 1. It moves the delay to before the DNS resolution (with the exponential back-off it might well be that the DNS records are changed while slixmpp is waiting). 2. It adds a new event `reconnect_delay` that gets passed the number of seconds it will delay before actually reconnecting 3. It resets the `connect_loop_wait` timer on a manual connect/reconnect call to fix the interactive experience. A *proper fix* would replace the sleep in `_connect_routine` with a properly timered re-invocation of it, but I don't understand enough of asyncio for pulling off that magic, and this is actually a proper improvement. Also I tested this and it works! --- slixmpp/xmlstream/xmlstream.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/slixmpp/xmlstream/xmlstream.py b/slixmpp/xmlstream/xmlstream.py index c3c82a37..cbb7950a 100644 --- a/slixmpp/xmlstream/xmlstream.py +++ b/slixmpp/xmlstream/xmlstream.py @@ -277,6 +277,7 @@ class XMLStream(asyncio.BaseProtocol): ) self.disconnect_reason = None self.cancel_connection_attempt() + self.connect_loop_wait = 0 if host and port: self.address = (host, int(port)) try: @@ -301,6 +302,10 @@ class XMLStream(asyncio.BaseProtocol): async def _connect_routine(self): self.event_when_connected = "connected" + if self.connect_loop_wait > 0: + self.event('reconnect_delay', self.connect_loop_wait) + await asyncio.sleep(self.connect_loop_wait, loop=self.loop) + record = await self.pick_dns_answer(self.default_domain) if record is not None: host, address, dns_port = record @@ -317,7 +322,6 @@ class XMLStream(asyncio.BaseProtocol): else: ssl_context = None - await asyncio.sleep(self.connect_loop_wait, loop=self.loop) if self._current_connection_attempt is None: return try: