简体   繁体   中英

Async DNS query function can only be called once per session

Probably this is a dumb question, I know this must be pretty trivial, and probably has been asked many times, but I don't know the answer and none of the answers I have found through Google solves the problem.

The problem is really simple, I used the example code from https://pypi.org/project/async-dns/ :

import asyncio
from async_dns.core import types, Address
from async_dns.resolver import DNSClient

async def query():
    client = DNSClient()
    res = await client.query('www.google.com', types.A,
                             Address.parse('8.8.8.8'))
    print(res)
    print(res.aa)

asyncio.run(query())

And it can only be called once without raising all kinds of exceptions, one of them being: RuntimeError: Event loop is closed

I have tried suggestions from "Asyncio Event Loop is Closed" when getting loop but no luck so far:

Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> from async_dns.core import types, Address
>>> from async_dns.resolver import DNSClient
>>>
>>> async def query():
...     client = DNSClient()
...     res = await client.query('www.google.com', types.A,
...                              Address.parse('8.8.8.8'))
...     print(res)
...     print(res.aa)
...
>>> asyncio.run(query())
<DNSMessage type=1 qid=35499 r=0 QD=[<Record type=request qtype=A name=www.google.com>] AN=[<Record type=response qtype=A name=www.google.com ttl=157 data=<a: 108.160.163.108>>] NS=[] AR=[]>
0
>>> asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
>>> loop = asyncio.new_event_loop()
>>> loop.run_until_complete(query())
Fatal write error on datagram transport
protocol: <async_dns.request.udp.CallbackProtocol object at 0x0000022AEE2491B0>
transport: <_ProactorDatagramTransport fd=528 read=<_OverlappedFuture cancelled>>
Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 528, in _loop_writing
    self._write_fut = self._loop._proactor.sendto(self._sock,
AttributeError: 'NoneType' object has no attribute 'sendto'
Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 528, in _loop_writing
    self._write_fut = self._loop._proactor.sendto(self._sock,
AttributeError: 'NoneType' object has no attribute 'sendto'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
    return future.result()
  File "<stdin>", line 3, in query
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 35, in query
    return await task
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 42, in _query
    res = await asyncio.wait_for(self._request(req, addr), self.timeout)
  File "C:\Program Files\Python310\lib\asyncio\tasks.py", line 447, in wait_for
    return fut.result()
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 51, in _request
    data = await request(req, addr, self.timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 111, in request
    data = await dispatcher.send(req, addr, timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 84, in send
    return await self._send(req.pack(), (host, port or 53), timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 77, in _send
    return await self.protocol.write_data(data, addr, timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 53, in write_data
    self.transport.sendto(data, addr)
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 501, in sendto
    self._loop_writing()
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 534, in _loop_writing
    self._fatal_error(exc, 'Fatal write error on datagram transport')
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 131, in _fatal_error
    self._force_close(exc)
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 151, in _force_close
    self._loop.call_soon(self._call_connection_lost, exc)
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 745, in call_soon
    self._check_closed()
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
>>> asyncio.set_event_loop(asyncio.new_event_loop())
>>> asyncio.get_event_loop()
<stdin>:1: DeprecationWarning: There is no current event loop
<_WindowsSelectorEventLoop running=False closed=False debug=False>
>>> asyncio.run(query())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
    return future.result()
  File "<stdin>", line 3, in query
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 35, in query
    return await task
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 42, in _query
    res = await asyncio.wait_for(self._request(req, addr), self.timeout)
  File "C:\Program Files\Python310\lib\asyncio\tasks.py", line 447, in wait_for
    return fut.result()
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 51, in _request
    data = await request(req, addr, self.timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 111, in request
    data = await dispatcher.send(req, addr, timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 84, in send
    return await self._send(req.pack(), (host, port or 53), timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 77, in _send
    return await self.protocol.write_data(data, addr, timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 53, in write_data
    self.transport.sendto(data, addr)
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 497, in sendto
    self._buffer.append((bytes(data), addr))
AttributeError: 'NoneType' object has no attribute 'append'
>>>

How can it be solved?

In cases like this, it's ususally a good idea to go to the project's GitHub and search for the error message in issues:

https://github.com/gera2ld/async_dns/issues?q=is%3Aissue+Event+loop+is+closed

It gives us one result and the solution is in the last comment:

https://github.com/gera2ld/async_dns/issues/26#issuecomment-844850252

The final code:

import asyncio
from async_dns.core import types, Address
from async_dns.resolver import DNSClient
from async_dns.request import clean


async def query():
    client = DNSClient()
    res = await client.query("www.google.com", types.A, Address.parse("8.8.8.8"))
    print(res)
    print(res.aa)
    clean()


asyncio.run(query())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM