1

私はPython 3.4.3を使用して、複数のURLに定期的にリクエストを送信しています。これが私が書いたコルーチンです (コードを簡素化するためにいくつかのエラー処理を省略しました):

@asyncio.coroutine
def ping(url, interval, session, *, loop):
    while True:
        try:
            with aiohttp.Timeout(interval):
                resp = yield from session.get(url)
                resp.close()

        except asyncio.TimeoutError:
            # continue sending requests anyway
            continue

        yield from asyncio.sleep(interval)

を使用して複数のpingコルーチンを開始してasyncio.gatherいます。しかし、サーバーの応答が長すぎると、InvalidStateError例外が発生することがあります。

Exception in callback <bound method Future.set_result of Future<CANCELLED>>(None,)
handle: Handle(<bound method Future.set_result of Future<CANCELLED>>, (None,))
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/events.py", line 39, in _run
    self._callback(*self._args)
  File "/usr/lib/python3.4/asyncio/futures.py", line 298, in set_result
    raise InvalidStateError('{}: {!r}'.format(self._state, self))
asyncio.futures.InvalidStateError: CANCELLED: Future<CANCELLED>

スクリプトは引き続き機能しますが、このトレースバックを黙らせるにはどうすればよいですか? それはバグですか、それとも私が間違っていることですか?

私が持っている唯一の考えは、Webサーバーが最終的に応答するときに、asyncio(またはaiohttp)Futureがすでにキャンセルされた結果にresultを設定しようとすることです。

編集:

pingそのコルーチンを開始する方法は次のとおりです。

@asyncio.coroutine
def main(loop, rules, session):
    tasks = [ping(url, interval, session, loop=loop)
             for url, interval in rules]
    try:
        yield from asyncio.gather(*tasks, loop=loop)
    except Exception:
        print('Cancelled!', file=sys.stderr)
        traceback.print_exc()


if __name__ == '__main__':
    rules = [('http://localhost:8080/1/', 5),
             ('http://localhost:8080/2/', 10)]

    loop = asyncio.get_event_loop()
    try:
        conn = aiohttp.TCPConnector(verify_ssl=False)
        with aiohttp.ClientSession(connector=conn) as session:
            loop.run_until_complete(main(loop=loop,
                                         rules=rules,
                                         session=session))
    except KeyboardInterrupt:
        print('Interrupted. Exiting', file=sys.stderr)
4

0 に答える 0