Implement offline timeouts
This commit is contained in:
parent
7d4e304565
commit
d406d269da
38
ethermess.py
38
ethermess.py
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
libexec_dir = __LIBEXECDIR__
|
||||
|
||||
offline_timeout = 5 * 60
|
||||
|
||||
import enum
|
||||
import select
|
||||
import subprocess
|
||||
|
@ -143,8 +145,6 @@ def handle_status(mac, status, nick):
|
|||
peers[mac] = Peer(nick = None, status = None, lastseen = None)
|
||||
|
||||
|
||||
peers[mac].lastseen = time.monotonic()
|
||||
|
||||
if peers[mac].nick is not None and peers[mac].status != statuses.offline and nick != peers[mac].nick:
|
||||
print('=== ~%s -> ~%s [%s]' % (peers[mac].nick, nick, format_mac(mac)))
|
||||
|
||||
|
@ -193,6 +193,8 @@ def handle_message(mac, message):
|
|||
print('<%s> %s' % (nick, line))
|
||||
|
||||
def eventloop(proc):
|
||||
global peers
|
||||
|
||||
# Create unbuffered version of stdin and close the old one as we
|
||||
# won't need it anymore
|
||||
unbuf_stdin = open(sys.stdin.buffer.fileno(), 'rb', buffering = 0)
|
||||
|
@ -207,7 +209,30 @@ def eventloop(proc):
|
|||
|
||||
running = True
|
||||
while running:
|
||||
for fd, event in poll.poll():
|
||||
# Handle offline timeouts
|
||||
now = time.monotonic()
|
||||
for mac, peer in peers.items():
|
||||
if peer.lastseen + offline_timeout < now:
|
||||
peer.status = statuses.offline
|
||||
print('<<< (timeout) ~%s [%s]' % (peer.nick, format_mac(mac)))
|
||||
|
||||
# Figure out how long to wait in poll()
|
||||
wait = None
|
||||
for peer in peers.values():
|
||||
if peer.status != statuses.offline:
|
||||
if wait is None or wait >= peer.lastseen + offline_timeout - now:
|
||||
wait = peer.lastseen + offline_timeout - now
|
||||
|
||||
# Clamp at 0
|
||||
if wait is not None and wait < 0:
|
||||
wait = 0
|
||||
|
||||
# Convert s to ms
|
||||
if wait is not None:
|
||||
wait = wait * 1000
|
||||
|
||||
# Process events
|
||||
for fd, event in poll.poll(wait):
|
||||
if fd == proc.stdout.fileno() and event & select.POLLIN:
|
||||
event_type = readall(proc.stdout, 1)
|
||||
if event_type == b's':
|
||||
|
@ -219,6 +244,8 @@ def eventloop(proc):
|
|||
|
||||
handle_status(source_mac, statuses(status), nick.decode('utf-8'))
|
||||
|
||||
peers[source_mac].lastseen = time.monotonic()
|
||||
|
||||
elif event_type == b'i':
|
||||
# Msgid for message
|
||||
msgid = readall_u16(proc.stdout)
|
||||
|
@ -234,6 +261,8 @@ def eventloop(proc):
|
|||
msgid = readall_u16(proc.stdout)
|
||||
print('(ack: %s %i)' % (format_mac(source_mac), msgid)) #debg
|
||||
|
||||
peers[source_mac].lastseen = time.monotonic()
|
||||
|
||||
elif event_type == b'A':
|
||||
# ACK not received (and message send failed)
|
||||
print('(ack failed)') #debg
|
||||
|
@ -246,6 +275,8 @@ def eventloop(proc):
|
|||
|
||||
handle_message(source_mac, message.decode('utf-8'))
|
||||
|
||||
peers[source_mac].lastseen = time.monotonic()
|
||||
|
||||
else:
|
||||
raise ValueError('Unknown event type from backend: %s' % repr(event_type))
|
||||
|
||||
|
@ -272,6 +303,7 @@ def eventloop(proc):
|
|||
|
||||
else:
|
||||
raise Exception('Unreachable')
|
||||
|
||||
def main():
|
||||
global own_nick, own_status
|
||||
|
||||
|
|
Loading…
Reference in New Issue