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
|
#!/usr/bin/env python3
|
||||||
libexec_dir = __LIBEXECDIR__
|
libexec_dir = __LIBEXECDIR__
|
||||||
|
|
||||||
|
offline_timeout = 5 * 60
|
||||||
|
|
||||||
import enum
|
import enum
|
||||||
import select
|
import select
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -143,8 +145,6 @@ def handle_status(mac, status, nick):
|
||||||
peers[mac] = Peer(nick = None, status = None, lastseen = None)
|
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:
|
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)))
|
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))
|
print('<%s> %s' % (nick, line))
|
||||||
|
|
||||||
def eventloop(proc):
|
def eventloop(proc):
|
||||||
|
global peers
|
||||||
|
|
||||||
# Create unbuffered version of stdin and close the old one as we
|
# Create unbuffered version of stdin and close the old one as we
|
||||||
# won't need it anymore
|
# won't need it anymore
|
||||||
unbuf_stdin = open(sys.stdin.buffer.fileno(), 'rb', buffering = 0)
|
unbuf_stdin = open(sys.stdin.buffer.fileno(), 'rb', buffering = 0)
|
||||||
|
@ -207,7 +209,30 @@ def eventloop(proc):
|
||||||
|
|
||||||
running = True
|
running = True
|
||||||
while running:
|
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:
|
if fd == proc.stdout.fileno() and event & select.POLLIN:
|
||||||
event_type = readall(proc.stdout, 1)
|
event_type = readall(proc.stdout, 1)
|
||||||
if event_type == b's':
|
if event_type == b's':
|
||||||
|
@ -219,6 +244,8 @@ def eventloop(proc):
|
||||||
|
|
||||||
handle_status(source_mac, statuses(status), nick.decode('utf-8'))
|
handle_status(source_mac, statuses(status), nick.decode('utf-8'))
|
||||||
|
|
||||||
|
peers[source_mac].lastseen = time.monotonic()
|
||||||
|
|
||||||
elif event_type == b'i':
|
elif event_type == b'i':
|
||||||
# Msgid for message
|
# Msgid for message
|
||||||
msgid = readall_u16(proc.stdout)
|
msgid = readall_u16(proc.stdout)
|
||||||
|
@ -234,6 +261,8 @@ def eventloop(proc):
|
||||||
msgid = readall_u16(proc.stdout)
|
msgid = readall_u16(proc.stdout)
|
||||||
print('(ack: %s %i)' % (format_mac(source_mac), msgid)) #debg
|
print('(ack: %s %i)' % (format_mac(source_mac), msgid)) #debg
|
||||||
|
|
||||||
|
peers[source_mac].lastseen = time.monotonic()
|
||||||
|
|
||||||
elif event_type == b'A':
|
elif event_type == b'A':
|
||||||
# ACK not received (and message send failed)
|
# ACK not received (and message send failed)
|
||||||
print('(ack failed)') #debg
|
print('(ack failed)') #debg
|
||||||
|
@ -246,6 +275,8 @@ def eventloop(proc):
|
||||||
|
|
||||||
handle_message(source_mac, message.decode('utf-8'))
|
handle_message(source_mac, message.decode('utf-8'))
|
||||||
|
|
||||||
|
peers[source_mac].lastseen = time.monotonic()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError('Unknown event type from backend: %s' % repr(event_type))
|
raise ValueError('Unknown event type from backend: %s' % repr(event_type))
|
||||||
|
|
||||||
|
@ -272,6 +303,7 @@ def eventloop(proc):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception('Unreachable')
|
raise Exception('Unreachable')
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global own_nick, own_status
|
global own_nick, own_status
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue