mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-08-06 10:31:42 +00:00
Refactor of caching & data storage part 2 #118
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
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 = 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._fan_out, value)
|
||||
|
||||
def _fan_out(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)
|
||||
Reference in New Issue
Block a user