@@ -12,7 +12,7 @@ def _critical_termination_listener(*_: object, **__: object) -> None:
1212 # Must be defined in the global namespace, as ayncpg keeps
1313 # a set of functions to call. This this will now happen once as
1414 # all instance will point to the same function.
15- logging .critical ("Connection is closed / terminated! " )
15+ logging .critical ("Connection is closed / terminated. " )
1616
1717
1818class PGEventQueue (asyncio .Queue [models .Event ]):
@@ -23,48 +23,59 @@ class PGEventQueue(asyncio.Queue[models.Event]):
2323
2424 def __init__ (
2525 self ,
26- pgchannel : models .PGChannel ,
27- pgconn : asyncpg .Connection ,
2826 max_size : int = 0 ,
2927 max_latency : datetime .timedelta = datetime .timedelta (milliseconds = 500 ),
30- _called_by_create : bool = False ,
3128 ) -> None :
32- """
33- Initializes the PGEventQueue instance. Use the create() classmethod to
34- instantiate.
35- """
36- if not _called_by_create :
37- raise RuntimeError (
38- "Use classmethod create(...) to instantiate PGEventQueue."
39- )
4029 super ().__init__ (maxsize = max_size )
41- self ._pg_channel = pgchannel
42- self ._pg_connection = pgconn
30+ self ._pg_channel : None | models . PGChannel = None
31+ self ._pg_connection : None | asyncpg . Connection = None
4332 self ._max_latency = max_latency
4433
45- @classmethod
46- async def create (
47- cls ,
48- pgchannel : models .PGChannel ,
49- pgconn : asyncpg .Connection ,
50- maxsize : int = 0 ,
51- max_latency : datetime .timedelta = datetime .timedelta (milliseconds = 500 ),
52- ) -> "PGEventQueue" :
53- """
54- Creates and initializes a new PGEventQueue instance, connecting to the specified
55- PostgreSQL channel. Returns the initialized PGEventQueue instance.
34+ async def connect (
35+ self ,
36+ connection : asyncpg .Connection ,
37+ channel : models .PGChannel ,
38+ ) -> None :
5639 """
57- me = cls (
58- pgchannel = pgchannel ,
59- pgconn = pgconn ,
60- max_size = maxsize ,
61- max_latency = max_latency ,
62- _called_by_create = True ,
40+ Asynchronously connects the PGEventQueue to a specified
41+ PostgreSQL channel and connection.
42+
43+ This method establishes a listener on a PostgreSQL channel
44+ using the provided connection. It is designed to be called
45+ once per PGEventQueue instance to ensure a one-to-one relationship
46+ between the event queue and a database channel. If an attempt is
47+ made to connect a PGEventQueue instance to more than one channel
48+ or connection, a RuntimeError is raised to enforce this constraint.
49+
50+ Parameters:
51+ - connection: asyncpg.Connection
52+ The asyncpg connection object to be used for listening to database events.
53+ - channel: models.PGChannel
54+ The database channel to listen on for events.
55+
56+ Raises:
57+ - RuntimeError: If the PGEventQueue is already connected to a
58+ channel or connection.
59+
60+ Usage:
61+ ```python
62+ await pg_event_queue.connect(
63+ connection=your_asyncpg_connection,
64+ channel=your_pg_channel,
6365 )
64- me ._pg_connection .add_termination_listener (_critical_termination_listener )
65- await me ._pg_connection .add_listener (me ._pg_channel , me .parse_and_put ) # type: ignore[arg-type]
66+ ```
67+ """
68+ if self ._pg_channel or self ._pg_connection :
69+ raise RuntimeError (
70+ "PGEventQueue instance is already connected to a channel and/or "
71+ "connection. Only supports one channel and connection per "
72+ "PGEventQueue instance."
73+ )
6674
67- return me
75+ self ._pg_channel = channel
76+ self ._pg_connection = connection
77+ self ._pg_connection .add_termination_listener (_critical_termination_listener )
78+ await self ._pg_connection .add_listener (self ._pg_channel , self .parse_and_put ) # type: ignore[arg-type]
6879
6980 def parse_and_put (
7081 self ,
@@ -87,6 +98,7 @@ def parse_and_put(
8798 except Exception :
8899 logging .exception ("Unable to parse `%s`." , payload )
89100 else :
101+ logging .info ("Received event: %s on %s" , parsed , channel )
90102 try :
91103 self .put_nowait (parsed )
92104 except Exception :
0 commit comments