2022-11-15 03:27:45 +00:00
|
|
|
import asyncio
|
2022-11-25 19:48:57 +00:00
|
|
|
import time
|
2022-11-15 03:27:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
class MessageStream:
|
|
|
|
"""
|
|
|
|
A message stream for consumers to subscribe to,
|
|
|
|
and for producers to publish to.
|
|
|
|
"""
|
|
|
|
def __init__(self):
|
|
|
|
self._loop = asyncio.get_running_loop()
|
|
|
|
self._waiter = self._loop.create_future()
|
|
|
|
|
|
|
|
def publish(self, message):
|
2022-11-25 19:48:57 +00:00
|
|
|
"""
|
|
|
|
Publish a message to this MessageStream
|
|
|
|
|
|
|
|
:param message: The message to publish
|
|
|
|
"""
|
2022-11-15 03:27:45 +00:00
|
|
|
waiter, self._waiter = self._waiter, self._loop.create_future()
|
2022-11-25 19:48:57 +00:00
|
|
|
waiter.set_result((message, time.time(), self._waiter))
|
2022-11-15 03:27:45 +00:00
|
|
|
|
2022-11-25 19:48:57 +00:00
|
|
|
async def __aiter__(self):
|
|
|
|
"""
|
|
|
|
Iterate over the messages in the message stream
|
|
|
|
"""
|
2022-11-15 03:27:45 +00:00
|
|
|
waiter = self._waiter
|
|
|
|
while True:
|
2022-11-18 20:32:27 +00:00
|
|
|
# Shield the future from being cancelled by a task waiting on it
|
2022-11-25 19:48:57 +00:00
|
|
|
message, ts, waiter = await asyncio.shield(waiter)
|
|
|
|
yield message, ts
|