mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-08-06 02:21:42 +00:00
39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
import logging
|
|
import threading
|
|
|
|
from tornado.ioloop import IOLoop
|
|
|
|
|
|
class SSEBroadcaster:
|
|
"""Bridge between DataStore listener callbacks (which fire on provider threads) to Tornado's async SSE handlers
|
|
(which live on the IOLoop thread) to avoid any interdependency between them."""
|
|
|
|
def __init__(self):
|
|
self._handlers = set()
|
|
self._lock = threading.Lock()
|
|
self._loop = None
|
|
|
|
def bind_to_web_server_loop(self):
|
|
self._loop = IOLoop.current()
|
|
|
|
def register(self, handler):
|
|
with self._lock:
|
|
self._handlers.add(handler)
|
|
|
|
def unregister(self, handler):
|
|
with self._lock:
|
|
self._handlers.discard(handler)
|
|
|
|
def publish(self, value):
|
|
self._loop.add_callback(self._broadcast, value)
|
|
|
|
def _broadcast(self, value):
|
|
with self._lock:
|
|
handlers = list(self._handlers)
|
|
for handler in handlers:
|
|
try:
|
|
handler.callback(value)
|
|
except Exception:
|
|
# Connection probably dropped, ignore and de-register the handler to stop getting future items.
|
|
logging.debug("Failed to push to an SSE client; dropping it")
|
|
self.unregister(handler) |