Skip to content

Commit 492f63d

Browse files
Logionizbdraco
andauthored
Fixed bug that lead to infinite wait for dns futures (#10529)
<!-- Thank you for your contribution! --> ## What do these changes do? Fixed bug that lead to infinite wait for dns futures when exception occured in trace.send_dns_cache_miss call. ## Are there changes in behavior for the user? No ## Is it a substantial burden for the maintainers to support this? No ## Related issue number No issue. ## Checklist - [x] I think the code is well written - [x] Unit tests for the changes exist - [x] Documentation reflects the changes - [x] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is &lt;Name&gt; &lt;Surname&gt;. * Please keep alphabetical order, the file is sorted by names. - [x] Add a new news fragment into the `CHANGES/` folder * name it `<issue_or_pr_num>.<type>.rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` --------- Co-authored-by: J. Nick Koston <[email protected]>
1 parent 44e669b commit 492f63d

File tree

4 files changed

+61
-3
lines changed

4 files changed

+61
-3
lines changed

CHANGES/10529.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed an issue where dns queries were delayed indefinitely when an exception occurred in a ``trace.send_dns_cache_miss``
2+
-- by :user:`logioniz`.

CONTRIBUTORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Alexandru Mihai
3131
Alexey Firsov
3232
Alexey Nikitin
3333
Alexey Popravka
34+
Alexey Stavrov
3435
Alexey Stepanov
3536
Almaz Salakhov
3637
Amin Etesamian

aiohttp/connector.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,11 +1018,11 @@ async def _resolve_host_with_throttle(
10181018
This method must be run in a task and shielded from cancellation
10191019
to avoid cancelling the underlying lookup.
10201020
"""
1021-
if traces:
1022-
for trace in traces:
1023-
await trace.send_dns_cache_miss(host)
10241021
try:
10251022
if traces:
1023+
for trace in traces:
1024+
await trace.send_dns_cache_miss(host)
1025+
10261026
for trace in traces:
10271027
await trace.send_dns_resolvehost_start(host)
10281028

tests/test_connector.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3683,6 +3683,61 @@ async def send_dns_cache_hit(self, *args: object, **kwargs: object) -> None:
36833683
await connector.close()
36843684

36853685

3686+
async def test_connector_resolve_in_case_of_trace_cache_miss_exception(
3687+
loop: asyncio.AbstractEventLoop,
3688+
) -> None:
3689+
token: ResolveResult = {
3690+
"hostname": "localhost",
3691+
"host": "127.0.0.1",
3692+
"port": 80,
3693+
"family": socket.AF_INET,
3694+
"proto": 0,
3695+
"flags": socket.AI_NUMERICHOST,
3696+
}
3697+
3698+
request_count = 0
3699+
3700+
class DummyTracer(Trace):
3701+
def __init__(self) -> None:
3702+
"""Dummy"""
3703+
3704+
async def send_dns_cache_hit(self, *args: object, **kwargs: object) -> None:
3705+
"""Dummy send_dns_cache_hit"""
3706+
3707+
async def send_dns_resolvehost_start(
3708+
self, *args: object, **kwargs: object
3709+
) -> None:
3710+
"""Dummy send_dns_resolvehost_start"""
3711+
3712+
async def send_dns_resolvehost_end(
3713+
self, *args: object, **kwargs: object
3714+
) -> None:
3715+
"""Dummy send_dns_resolvehost_end"""
3716+
3717+
async def send_dns_cache_miss(self, *args: object, **kwargs: object) -> None:
3718+
nonlocal request_count
3719+
request_count += 1
3720+
if request_count <= 1:
3721+
raise Exception("first attempt")
3722+
3723+
async def resolve_response() -> List[ResolveResult]:
3724+
await asyncio.sleep(0)
3725+
return [token]
3726+
3727+
with mock.patch("aiohttp.connector.DefaultResolver") as m_resolver:
3728+
m_resolver().resolve.return_value = resolve_response()
3729+
3730+
connector = TCPConnector()
3731+
traces = [DummyTracer()]
3732+
3733+
with pytest.raises(Exception):
3734+
await connector._resolve_host("", 0, traces)
3735+
3736+
await connector._resolve_host("", 0, traces) == [token]
3737+
3738+
await connector.close()
3739+
3740+
36863741
async def test_connector_does_not_remove_needed_waiters(
36873742
loop: asyncio.AbstractEventLoop, key: ConnectionKey
36883743
) -> None:

0 commit comments

Comments
 (0)