如何使用 asyncio 清除和改进此 python 代码?

How to clear and improve this python code using asyncio?

我正在编写一个 python 脚本来监控多个站点的状态。
因为它应该以精确的时间间隔检查网站状态而不会被其他网站检查阻止,所以我正在使用 asyncio。
但是看起来我在捕捉到 SIGINT 信号时没有正确停止它,或者可能是我做错了所有事情。

/usr/lib/python3.5/asyncio/unix_events.py:129: RuntimeWarning: coroutine 'exit_sigint' was never awaited
  del self._signal_handlers[sig]
exception calling callback for <Future at 0x7f146da3ee80 state=finished returned list>
Traceback (most recent call last):
  File "/usr/lib/python3.5/concurrent/futures/_base.py", line 297, in _invoke_callbacks
    callback(self)
  File "/usr/lib/python3.5/asyncio/futures.py", line 442, in _call_set_state
    dest_loop.call_soon_threadsafe(_set_state, destination, source)
  File "/usr/lib/python3.5/asyncio/base_events.py", line 532, in call_soon_threadsafe
    handle = self._call_soon(callback, args)
  File "/usr/lib/python3.5/asyncio/base_events.py", line 506, in _call_soon
    self._check_closed()
  File "/usr/lib/python3.5/asyncio/base_events.py", line 334, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

源代码:
https://github.com/DasFranck/Python-Mineur/blob/master/awsum_py/awsum.py

我应该改变什么,我做对了什么?

根据 asyncio doc :

ensure_future schedules the execution of a coroutine object: wrap it in a future. Return a Task object.

你的回调运行一个协程,它应该由你的循环管理,但你从来没有 run_until_complete 它,所以你永远不会等待它完成。事实上,通过像这样包装回调,您不能在其上调用 run_until_complete

无论如何,回调不必是异步的,所以你可以像这样使用它们:

# exit_sigint doesn't even need the loop as a parameter
def exit_sigint(signame):
  print("%s catched, exiting..." % signame)
  for task in asyncio.Task.all_tasks():
    task.cancel()

loop.add_signal_handler(getattr(signal, "SIGINT"), exit_sigint, "SIGINT")
loop.add_signal_handler(getattr(signal, "SIGTERM"), exit_sigint, "SIGTERM")

没有将它们包装成未来。