I can post the code, I just thought it might be too much. However, I'll just post the relevant section. Contrary to multithreaded programming here most of the times the local section is enough (I love asyncio :))
try:
self.event_loop.run_forever()
except KeyboardInterrupt:
exit_main_loop()
finally:
print("Running shutdown cleanup")
collector.cancel()
@asyncio.coroutine
def shutdown():
yield from self.connection_pool.close()
self.event_loop.run_until_complete(shutdown())
self.event_loop.close()
And the close method:
@asyncio.coroutine
def close(self):
try:
if self.returned_connections:
msg = ("Not all connections were returned: %s"
% self.returned_connections)
log.error(msg)
raise ValueError(msg)
finally:
conn_tasks = [asyncio.Task(conn.disconnect())
for conn in self.all_connections]
done, pending = yield from asyncio.wait(conn_tasks, timeout=5)
assert not pending
Relevant is the finally part: I wrap each connection in a task and wait for them together. Removing the timeout did not help (I didn't expect it would, no exception is raised).
Per existing connection (up to 10) a message is produced:
2014-03-27 23:11:58,143 ERROR[asyncio] Coroutine 'disconnect' defined at /path/to/library/connection.py:109 was never yielded from
I have made sure that the amount of logging messages matches exactly the number of connections created (by counting the logging messages inside connection's __init__ function). In a very simple case there was only one connection, so only one error entry and only one log entry for a created connection.
Hope this additional information helps uncover the issue. Thanks for the response.