Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Queue message broadcasts locally in each IRCClient
Right now the trace of broadcasts is: RC2UDPHandler -> Broadcast task -> IRCServer.broadcast() -> for each IRCClient: -> IRCClient.msg() -> IRCClient.send() -> asyncio.StreamWriter.write() asyncio.StreamWriter.drain() So effectively, a task is spawned for every received message, but each of those tasks ends up awaiting drain() for every client. This means backtpressure from even a single client slows down every task, ultimately slowing down processing, as well as creating a thundering herd problem. This could be easily fixed by just removing the "await ...drain()" from IRCClient.send(), or creating a no_drain=True variant. However, this means that super slow clients may potentially accumulate large buffers of messages to be sent. Instead, create an asyncio.Queue() in each IRCClient, holding each client's backlog, and a single task per client to consume from this queue. The queue size is capped at a certain (arbitrary) size, after which the queue just drops all new messages. Metrics have been added to monitor overruns and potentially adjust this size.
- Loading branch information