Hi Glyph, hi Guido, hi everyone. You have two very different points of critique, let me respond to both of them:
> StreamWriter.drain cannot be called from different tasks (asyncio tasks that > is) > at the same time. > > > In my opinion, this is fine. It should probably be some exception other than > AssertionError, but it should be an exception. Do not try to manipulate a > StreamWriter or a StreamReader from multiple tasks at once. If you encourage > people to do this, it is a recipe for corrupted output streams and > interleaved writes. No, it isn't. Asyncio is completely single threaded, only one task is running at any given time, until the next yield from. So no writes can ever be interleaved, unless you explicitly yield from something. As an example, in my code I am calling something like: writer.write(header) writer.write(payload) While everyone trained in multi-threaded code will get a heart attack reading this code, it's no issue whatsoever with asyncio: the two calls to write will always nicely follow each other without any interleaving, as there simply is no other thread that could do anything. > Agreed. These streams should not be accessed "concurrently" by different > coroutines. A single coroutine that repeatedly calls write() and eventually > drain() is in full control over how many bytes it writes before calling > drain(), and thus it can easily ensure the memory needed for buffering is > strictly bounded. But if multiple independent coroutines engage in this > pattern for the same stream, the amount of buffer space is not under control > of any single coroutine. Guido definitely has a point here. But this problem is solvable: in a system where the writer is slow - and this is the situation you typically want to use drain() - all tasks will normally be waiting in drain until the writer reached its low water mark again. Now my patch will resume all tasks. That is wrong. The correct solution is to resume only one task (first come first serve probably being best), and the others only once the writer is fine again. This is how I will solve it in my project. If someone is interested, I could also post the result here. Greetings Martin