Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The standard Python asyncio Transport classes protect their caller from having to deal with exceptions when calling .write(). In case an exception does occur, they capture it and close the transport, passing the exception on to the connection_lost() handler. This makes it a lot easier to interact with the transport: because OS-level errors are handled out of band, protocols don't have to consider that any write might fail. Our Transport classes do the same thing, but there's an important difference: the standard library defers the call to .connection_lost(), but our transports invoke it immediately. This creates a weird scenario whereby your connection_lost() handler can get called in the middle of your connection_made() handler, if you should happen to do a .write() there which fails. Since connection_lost() reasonably assumes that connection_made() has run, you can get into all kinds of trouble. Worst of all, once .connection_lost() is done running, control flow returns back to your .connection_made() handler, which continues running as if nothing has happened in the meantime. Let's adopt the standard Python behaviour here and defer the .connection_lost() call. We need to adjust some unit tests which assumed the old behaviour: adjust them to ensure that we specifically *don't* have that behaviour anymore.
- Loading branch information