trackers
This commit is contained in:
+44
-37
@@ -219,46 +219,55 @@ class TaskManager:
|
|||||||
self, txid: str, queue: asyncio.Queue[OnchainTxEvent]
|
self, txid: str, queue: asyncio.Queue[OnchainTxEvent]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a per-connection queue for a watched transaction."""
|
"""Register a per-connection queue for a watched transaction."""
|
||||||
self._ws_tx_queues.setdefault(txid, []).append(queue)
|
self._get_tx_tracker(txid).register_queue(queue)
|
||||||
if len(self._ws_tx_queues[txid]) == 1:
|
|
||||||
self.create_task(
|
|
||||||
self._transaction_tracker_dispatch(txid), name=f"ws_tx_{txid}"
|
|
||||||
)
|
|
||||||
|
|
||||||
def unregister_ws_tx_queue(
|
def unregister_ws_tx_queue(
|
||||||
self, txid: str, queue: asyncio.Queue[OnchainTxEvent]
|
self, txid: str, queue: asyncio.Queue[OnchainTxEvent]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Deregister a per-connection queue; cancel tracker when last one leaves."""
|
"""Deregister a per-connection queue; cancel tracker when last one leaves."""
|
||||||
queues = self._ws_tx_queues.get(txid, [])
|
tracker = self._tx_trackers.get(txid)
|
||||||
if queue in queues:
|
if not tracker:
|
||||||
queues.remove(queue)
|
return
|
||||||
if not queues:
|
tracker.unregister_queue(queue)
|
||||||
self._ws_tx_queues.pop(txid, None)
|
if not tracker.has_queues():
|
||||||
|
self._tx_trackers.pop(txid, None)
|
||||||
task = self.get_task(f"ws_tx_{txid}")
|
task = self.get_task(f"ws_tx_{txid}")
|
||||||
if task:
|
if task:
|
||||||
self.cancel_task(task)
|
self.cancel_task(task)
|
||||||
|
|
||||||
|
def _get_tx_tracker(self, txid: str) -> "TransactionTracker":
|
||||||
|
tracker = self._tx_trackers.get(txid)
|
||||||
|
if tracker is None:
|
||||||
|
tracker = TransactionTracker(settings.lnbits_blockexplorer_electrum_url)
|
||||||
|
self._tx_trackers[txid] = tracker
|
||||||
|
if not self.get_task(f"ws_tx_{txid}"):
|
||||||
|
self.create_task(
|
||||||
|
self._transaction_tracker_dispatch(txid, tracker),
|
||||||
|
name=f"ws_tx_{txid}",
|
||||||
|
)
|
||||||
|
return tracker
|
||||||
|
|
||||||
def register_ws_block_queue(self, queue: asyncio.Queue[BlockInfo]) -> None:
|
def register_ws_block_queue(self, queue: asyncio.Queue[BlockInfo]) -> None:
|
||||||
"""Register a per-connection queue for new block events."""
|
"""Register a per-connection queue for new block events."""
|
||||||
self._ws_block_queues.append(queue)
|
if self._block_tracker is None:
|
||||||
if len(self._ws_block_queues) == 1:
|
self._block_tracker = BlockTracker(
|
||||||
if self._block_tracker is None:
|
settings.lnbits_blockexplorer_electrum_url
|
||||||
self._block_tracker = BlockTracker(
|
)
|
||||||
settings.lnbits_blockexplorer_electrum_url
|
tracker = self._block_tracker
|
||||||
)
|
was_empty = not tracker.has_queues()
|
||||||
|
tracker.register_queue(queue)
|
||||||
|
if was_empty:
|
||||||
self.create_task(
|
self.create_task(
|
||||||
self._block_tracker.run(
|
tracker.run(lambda: tracker.has_queues() and settings.lnbits_running),
|
||||||
self._dispatch_block_event,
|
|
||||||
lambda: bool(self._ws_block_queues) and settings.lnbits_running,
|
|
||||||
),
|
|
||||||
name="block_tracker",
|
name="block_tracker",
|
||||||
)
|
)
|
||||||
|
|
||||||
def unregister_ws_block_queue(self, queue: asyncio.Queue[BlockInfo]) -> None:
|
def unregister_ws_block_queue(self, queue: asyncio.Queue[BlockInfo]) -> None:
|
||||||
"""Deregister a per-connection queue; cancel tracker when last one leaves."""
|
"""Deregister a per-connection queue; cancel tracker when last one leaves."""
|
||||||
if queue in self._ws_block_queues:
|
if not self._block_tracker:
|
||||||
self._ws_block_queues.remove(queue)
|
return
|
||||||
if not self._ws_block_queues:
|
self._block_tracker.unregister_queue(queue)
|
||||||
|
if not self._block_tracker.has_queues():
|
||||||
task = self.get_task("block_tracker")
|
task = self.get_task("block_tracker")
|
||||||
if task:
|
if task:
|
||||||
self.cancel_task(task)
|
self.cancel_task(task)
|
||||||
@@ -353,16 +362,6 @@ class TaskManager:
|
|||||||
if task.onchain_queue:
|
if task.onchain_queue:
|
||||||
task.onchain_queue.put_nowait(event)
|
task.onchain_queue.put_nowait(event)
|
||||||
|
|
||||||
async def _dispatch_onchain_tx_event(self, event: OnchainTxEvent) -> None:
|
|
||||||
"""Dispatches a tx event to all WS queues watching that txid."""
|
|
||||||
for q in list(self._ws_tx_queues.get(event.txid, [])):
|
|
||||||
q.put_nowait(event)
|
|
||||||
|
|
||||||
async def _dispatch_block_event(self, event: BlockInfo) -> None:
|
|
||||||
"""Dispatches a new block event to all WS queues."""
|
|
||||||
for q in list(self._ws_block_queues):
|
|
||||||
q.put_nowait(event)
|
|
||||||
|
|
||||||
async def _invoice_listener_consumer(self) -> None:
|
async def _invoice_listener_consumer(self) -> None:
|
||||||
payment = await self.invoice_queue.get()
|
payment = await self.invoice_queue.get()
|
||||||
logger.info(f"got a payment notification {payment.checking_id}")
|
logger.info(f"got a payment notification {payment.checking_id}")
|
||||||
@@ -382,13 +381,21 @@ class TaskManager:
|
|||||||
lambda: settings.lnbits_running,
|
lambda: settings.lnbits_running,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _transaction_tracker_dispatch(self, txid: str) -> None:
|
async def _transaction_tracker_dispatch(
|
||||||
await TransactionTracker(settings.lnbits_blockexplorer_electrum_url).track(
|
self, txid: str, tracker: "TransactionTracker"
|
||||||
|
) -> None:
|
||||||
|
"""Runs a shared tracker whose events are fanned out to its own
|
||||||
|
registered queues; no separate callback dispatch is needed."""
|
||||||
|
await tracker.track(
|
||||||
txid,
|
txid,
|
||||||
self._dispatch_onchain_tx_event,
|
self._noop_tx_callback,
|
||||||
lambda: txid in self._ws_tx_queues and settings.lnbits_running,
|
lambda: tracker.has_queues() and settings.lnbits_running,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def _noop_tx_callback(_: OnchainTxEvent) -> None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar("T", bound=BaseModel)
|
T = TypeVar("T", bound=BaseModel)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user