ntfy-waiter: never drop notifications, but rather sleep until client is ready to receive them

This commit is contained in:
Colin 2023-10-22 12:10:52 +00:00
parent 7541d5466e
commit b10425f6b6

View File

@ -24,15 +24,15 @@ class Client:
def __cmp__(self, other: 'Client'): def __cmp__(self, other: 'Client'):
return cmp(self.addr_info, other.addr_info) 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). returns true if we send a packet to notify client.
true otherwise. fals otherwise (e.g. the socket is dead).
""" """
if time.time() < self.live_after: ttl = self.live_after - time.time()
# TODO: we want to still notify, just with a delay! if ttl > 0:
logger.debug(f"not notifying client because it's not ready: {self.addr_info}") logger.debug(f"sleeping {ttl:.2f}s until client {self.addr_info} is ready to receive notification")
return True time.sleep(ttl)
try: try:
self.sock.sendall(message) self.sock.sendall(message)
@ -77,12 +77,13 @@ class Adapter:
self.add_client(Client(conn, addr_info, live_after = time.time() + self.silence)) self.add_client(Client(conn, addr_info, live_after = time.time() + self.silence))
def notify_clients(self, message: bytes = WAKE_MESSAGE): def notify_clients(self, message: bytes = WAKE_MESSAGE):
# notify every client, and drop any which have disconnected # notify every client, and drop any which have disconnected.
# XXX: paranoia about me not knowing Python's guarantees for mutation during set iteration # note that we notify based on age (oldest -> youngest)
clients = set(self.clients) # 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 = [ 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: for c in dead_clients:
self.clients.remove(c) self.clients.remove(c)