diff --git a/chatmaild/src/chatmaild/metadata.py b/chatmaild/src/chatmaild/metadata.py index 0cfc4817..7a55edec 100644 --- a/chatmaild/src/chatmaild/metadata.py +++ b/chatmaild/src/chatmaild/metadata.py @@ -1,6 +1,7 @@ import pwd from queue import Queue +from threading import Thread from socketserver import ( UnixStreamServer, StreamRequestHandler, @@ -31,21 +32,24 @@ class Notifier: def new_message_for_guid(self, guid): self.to_notify_queue.put(guid) - def thread_run(self): + def thread_run_loop(self): requests_session = requests.Session() while 1: - guid = self.to_notify_queue.get() - token = self.guid2token.get(guid) - if token: - response = requests_session.post( - "https://notifications.delta.chat/notify", - data=token, - timeout=60, - ) - if response.status_code == 410: - # 410 Gone status code - # means the token is no longer valid. - del self.guid2token[guid] + self.thread_run_one(requests_session) + + def thread_run_one(self, requests_session): + guid = self.to_notify_queue.get() + token = self.guid2token.get(guid) + if token: + response = requests_session.post( + "https://notifications.delta.chat/notify", + data=token, + timeout=60, + ) + if response.status_code == 410: + # 410 Gone status code + # means the token is no longer valid. + del self.guid2token[guid] def handle_dovecot_protocol(rfile, wfile, notifier): @@ -131,6 +135,13 @@ def main(): except FileNotFoundError: pass + # start notifier thread for signalling new messages to + # Delta Chat notification server + + t = Thread(target=notifier.thread_run_loop) + t.setDaemon(1) + t.start() + with ThreadedUnixStreamServer(socket, Handler) as server: os.chown(socket, uid=passwd_entry.pw_uid, gid=passwd_entry.pw_gid) try: diff --git a/chatmaild/src/chatmaild/tests/test_metadata.py b/chatmaild/src/chatmaild/tests/test_metadata.py index e0b66405..051ec747 100644 --- a/chatmaild/src/chatmaild/tests/test_metadata.py +++ b/chatmaild/src/chatmaild/tests/test_metadata.py @@ -87,3 +87,45 @@ def test_handle_dovecot_protocol_messagenew(): assert wfile.getvalue() == b"O\n" assert notifier.to_notify_queue.get() == "guid00" assert notifier.to_notify_queue.qsize() == 0 + + +def test_notifier_thread_run(): + requests = [] + + class ReqMock: + def post(self, url, data, timeout): + requests.append((url, data, timeout)) + + class Result: + status_code = 200 + + return Result() + + notifier = Notifier() + notifier.set_token("guid00", "01234") + notifier.new_message_for_guid("guid00") + notifier.thread_run_one(ReqMock()) + url, data, timeout = requests[0] + assert data == "01234" + + +def test_notifier_thread_run_gone_removes_token(): + requests = [] + + class ReqMock: + def post(self, url, data, timeout): + requests.append((url, data, timeout)) + + class Result: + status_code = 410 + + return Result() + + notifier = Notifier() + notifier.set_token("guid00", "01234") + notifier.new_message_for_guid("guid00") + assert notifier.guid2token["guid00"] == "01234" + notifier.thread_run_one(ReqMock()) + url, data, timeout = requests[0] + assert data == "01234" + assert len(notifier.guid2token) == 0