29 lines
1019 B
Python
29 lines
1019 B
Python
"""In-process idempotent event delivery for the single-stage protocol."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from copy import deepcopy
|
|
from typing import Any
|
|
|
|
|
|
class IdempotentInProcessPublisher:
|
|
"""A small delivery adapter with durable-outbox compatible semantics.
|
|
|
|
The process-local sink is intentionally only a delivery mechanism: SQLite
|
|
remains the durable event source. The event ID is retained so a later
|
|
durable broker/websocket adapter can make the same idempotency guarantee.
|
|
"""
|
|
|
|
def __init__(self) -> None:
|
|
self._seen_event_ids: set[int] = set()
|
|
self.delivered: list[dict[str, Any]] = []
|
|
|
|
async def publish(self, event: dict[str, Any]) -> None:
|
|
event_id = event.get("event_id")
|
|
if not isinstance(event_id, int):
|
|
raise ValueError("Published outbox event has no integer event_id")
|
|
if event_id in self._seen_event_ids:
|
|
return
|
|
self._seen_event_ids.add(event_id)
|
|
self.delivered.append(deepcopy(event))
|