From b10425f6b65e0eecccf80603e776b8dca9b2267b Mon Sep 17 00:00:00 2001 From: Colin Date: Sun, 22 Oct 2023 12:10:52 +0000 Subject: [PATCH] ntfy-waiter: never drop notifications, but rather sleep until client is ready to receive them --- hosts/by-name/servo/services/ntfy/ntfy-waiter | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/hosts/by-name/servo/services/ntfy/ntfy-waiter b/hosts/by-name/servo/services/ntfy/ntfy-waiter index 5990ed2e..8791d47a 100755 --- a/hosts/by-name/servo/services/ntfy/ntfy-waiter +++ b/hosts/by-name/servo/services/ntfy/ntfy-waiter @@ -24,15 +24,15 @@ class Client: def __cmp__(self, other: 'Client'): return cmp(self.addr_info, other.addr_info) - def maybe_notify(self, message: bytes) -> bool: + def try_notify(self, message: bytes) -> bool: """ - returns false if we wanted to notify the client but failed (e.g. socket died). - true otherwise. + returns true if we send a packet to notify client. + fals otherwise (e.g. the socket is dead). """ - if time.time() < self.live_after: - # TODO: we want to still notify, just with a delay! - logger.debug(f"not notifying client because it's not ready: {self.addr_info}") - return True + ttl = self.live_after - time.time() + if ttl > 0: + logger.debug(f"sleeping {ttl:.2f}s until client {self.addr_info} is ready to receive notification") + time.sleep(ttl) try: self.sock.sendall(message) @@ -77,12 +77,13 @@ class Adapter: self.add_client(Client(conn, addr_info, live_after = time.time() + self.silence)) def notify_clients(self, message: bytes = WAKE_MESSAGE): - # notify every client, and drop any which have disconnected - # XXX: paranoia about me not knowing Python's guarantees for mutation during set iteration - clients = set(self.clients) + # notify every client, and drop any which have disconnected. + # note that we notify based on age (oldest -> youngest) + # because notifying young clients might entail sleeping until they're ready. + clients = sorted(self.clients, key=lambda c: (c.live_after, c.addr_info)) dead_clients = [ - c for c in clients if not c.maybe_notify(message) + c for c in clients if not c.try_notify(message) ] for c in dead_clients: self.clients.remove(c)