On Monday, June 15, 2015 at 10:49:28 PM UTC+3, Guido van Rossum wrote: > > Fair enough. I guess there is a real danger to overwhelm the socket? > Otherwise you don't even need the drain() call. But it looks like you are > basically logging as fast as you can, so the drain() seems important. >
I still think that this is a relatively rare case and I don't want to > encourage sharing streams between coroutines. Maybe you can submit a patch > to turn the assert into a RuntimeError? > My 5c: I'm writing an AMQP client library. The AMQP protocol consists of a sequence of frames, which may (mostly) be interleaved. I use StreamWriter.drain() before sending large frames to make sure I'm not flooding the write buffer. I ran into this AssertionError while testing publishing messages from multiple tasks works - it didn't. Thinking there's some inherent reason drain() must be called from only one task, I started figuring out what logic I need to determine when to call it with the assumption it returns only when the buffer is empty. Instead it turns out it has water marks and the works, so I just wrapped the call in async with an asyncio.Lock. I'm not sure the AssertionError is more help than harm, as protocols such as this one where several tasks may operate on the same protocol just need to work around it, and protocols that don't support interleaving of writes probably run into bugs anyway. -- Mathias