diff --git a/lymph/core/connection.py b/lymph/core/connection.py index bc52947..011f300 100644 --- a/lymph/core/connection.py +++ b/lymph/core/connection.py @@ -31,12 +31,12 @@ def __init__(self, server, endpoint, heartbeat_interval=1, timeout=1, idle_timeo now = time.monotonic() self.last_seen = 0 - self.idle_since = 0 self.last_message = now self.created_at = now self.heartbeat_samples = SampleWindow(100, factor=1000) # milliseconds self.explicit_heartbeat_count = 0 self.status = UNKNOWN + self.last_status_change = now self.received_message_count = 0 self.sent_message_count = 0 @@ -60,10 +60,13 @@ def phi(self): return -math.log10(p) def set_status(self, status): + if status != self.status: + self.last_status_change = time.monotonic() + self.status = status def heartbeat_loop(self): - while True: + while self.status != CLOSED: start = time.monotonic() channel = self.server.ping(self.endpoint) try: @@ -76,7 +79,7 @@ def heartbeat_loop(self): gevent.sleep(self.heartbeat_interval) def live_check_loop(self): - while True: + while self.status != CLOSED: self.update_status() self.log_stats() gevent.sleep(self.timeout) @@ -84,11 +87,16 @@ def live_check_loop(self): def update_status(self): if self.last_seen: now = time.monotonic() - if now - self.last_seen >= self.timeout: + + if self.status == UNRESPONSIVE and now - self.last_status_change >= self.unresponsive_disconnect: + logger.debug("disconnecting from unresponsive endpoint %s" % (self.endpoint)) + self.close() + elif now - self.last_seen >= self.timeout: self.set_status(UNRESPONSIVE) + elif self.status == IDLE and now - self.last_status_change >= self.idle_disconnect: + self.close() elif now - self.last_message >= self.idle_timeout: self.set_status(IDLE) - self.idle_since = now else: self.set_status(RESPONSIVE) @@ -108,8 +116,6 @@ def close(self): if self.status == CLOSED: return self.status = CLOSED - self.heartbeat_loop_greenlet.kill() - self.live_check_loop_greenlet.kill() self.server.disconnect(self.endpoint) def on_recv(self, msg):