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.


Reply via email to