From b2872db6e3e6351c20f338d677c5ac3107d386df Mon Sep 17 00:00:00 2001 From: l_samenv Date: Wed, 15 May 2024 18:31:00 +0200 Subject: [PATCH] fix bug when connection is interrupted on the hw connection + stop listening for 10 seconds after an error --- router.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/router.py b/router.py index 2f01a01..0ac1300 100644 --- a/router.py +++ b/router.py @@ -168,6 +168,9 @@ class Router(IoHandler): except Exception as e: msg = f'error in request: {e!r}' self.service.failures[self.service.port] = msg + Service.deadline = time.time() + 10 + Service.reopen.append(self.service) + self.service.close() log.error(msg) self.close() @@ -345,6 +348,8 @@ class Service: failures = {} firewall_ports = set() tmo = 5 + reopen = [] + deadline = None def __init__(self, port, addr, iocls, maxcount=None, handler_args=()): self.handlers = {} @@ -399,6 +404,21 @@ class Service: self.failures.pop(self.port, None) self.handlers[handler.fno] = handler + def close(self): + s = self.socket + self.readers.pop(s.fileno(), None) + s.close() + + def clone(self): + return type(self)(self.port, self.addr, self.iocls) + + @classmethod + def check_deadline(cls): + if cls.deadline and time.time() > cls.deadline: + cls.deadline = None + while cls.reopen: + cls.reopen.pop().clone() + @classmethod def run(cls, routes): firewall = routes.pop('firewall', None) @@ -433,7 +453,8 @@ class Service: if ready: break else: - ready, complete, _ = select(cls.readers, [], []) + ready, complete, _ = select(cls.readers, [], [], 1) + cls.check_deadline() # log.debug('ready %r', ready) except Exception as e: for fno in cls.readers: @@ -448,7 +469,7 @@ class Service: log.error('%r in select([],[%d])', e, fno) raise for fno in ready: - cls.readers[fno]() + cls.readers.get(fno, int)() # int() -> dummy function if __name__ == '__main__':