Rewrite Client.run yet again.

This time it should definitely fix #545.
This commit is contained in:
Rapptz 2017-05-20 14:29:33 -04:00
parent 6e2ecbc167
commit 9e24d43c63

View File

@ -452,31 +452,46 @@ class Client:
yield from self.login(*args, bot=bot) yield from self.login(*args, bot=bot)
yield from self.connect(reconnect=reconnect) yield from self.connect(reconnect=reconnect)
def _do_cleanup(self): def _do_cleanup(self):
log.info('Cleaning up event loop.')
loop = self.loop loop = self.loop
if loop.is_closed(): if loop.is_closed():
return # we're already cleaning up return # we're already cleaning up
if loop.is_running(): task = compat.create_task(self.close(), loop=loop)
def _silence_gathered(fut):
try:
fut.result()
except:
pass
finally:
loop.stop() loop.stop()
loop.run_until_complete(self.close()) def when_future_is_done(fut):
pending = asyncio.Task.all_tasks(loop=loop) pending = asyncio.Task.all_tasks(loop=loop)
if pending: if pending:
log.info('Cleaning up after %s tasks', len(pending)) log.info('Cleaning up after %s tasks', len(pending))
gathered = asyncio.gather(*pending, loop=loop) gathered = asyncio.gather(*pending, loop=loop)
try:
gathered.cancel() gathered.cancel()
loop.run_until_complete(gathered) gathered.add_done_callback(_silence_gathered)
else:
loop.stop()
# we want to retrieve any exceptions to make sure that task.add_done_callback(when_future_is_done)
# they don't nag us about it being un-retrieved. if not loop.is_running():
gathered.exception() loop.run_forever()
else:
# on Linux, we're still running because we got triggered via
# the signal handler rather than the natural KeyboardInterrupt
# Since that's the case, we're going to return control after
# registering the task for the event loop to handle later
return None
try:
return task.result() # suppress unused task warning
except: except:
pass return None
loop.close()
def run(self, *args, **kwargs): def run(self, *args, **kwargs):
"""A blocking call that abstracts away the `event loop`_ """A blocking call that abstracts away the `event loop`_
@ -524,7 +539,8 @@ class Client:
if is_windows: if is_windows:
self._do_cleanup() self._do_cleanup()
if task.cancelled(): loop.close()
if task.cancelled() or not task.done():
return None return None
return task.result() return task.result()