GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-79033: Try to fix asyncio.Server.wait_closed() again by gvanrossum · Pull Request #111336 · python/cpython

Conversation

@gvanrossum

@gvanrossum gvanrossum commented Oct 25, 2023 •
edited by github-actions Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

I identified the condition that wait_closed() is intended to wait for: the server is closed and there are no more active connections.

When this condition first becomes true, _wakeup() is called (either from close() or from _detach()) and it sets _waiters to None. So we just check for self._waiters is None; if it's not None, we know we have to wait, and do so.

A problem was that the new test introduced in 3.12 explicitly tested that wait_closed() returns immediately when the server is not closed but there are currently no active connections. This was a mistake (probably a misunderstanding of the intended semantics). I've fixed the test, and added a separate test that checks exactly for this scenario.

I also fixed an oddity where in _wakeup() the result of the waiter was set to the waiter itself. This result is not used anywhere and I changed this to None, to avoid a GC cycle.

  • Issue: Counter-intuitive behavior of Server.close() / wait_closed() #79033

📚 Documentation preview 📚: https://cpython-previews--111336.org.readthedocs.build/

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@gvanrossum
Try to fix asyncio.Server.wait_closed() again
503f0bd
I identified the condition that `wait_closed()` is intended
to wait for: the server is closed *and* there are no more
active connections.

When this condition first becomes true, `_wakeup()` is called
(either from `close()` or from `_detach()`) and it sets `_waiters`
to `None`. So we just check for `self._waiters is None`; if it's
not `None`, we know we have to wait, and do so.

A problem was that the new test introduced in 3.12 explicitly
tested that `wait_closed()` returns immediately when the server
is *not* closed but there are currently no active connections.
This was a mistake (probably a misunderstanding of the intended
semantics). I've fixed the test, and added a separate test that
checks exactly for this scenario.

I also fixed an oddity where in `_wakeup()` the result of the
waiter was set to the waiter itself. This result is not used
anywhere and I changed this to `None`, to avoid a GC cycle.
@gvanrossum
gvanrossum requested review from 1st1, asvetlov, kumaraditya303 and willingc as code owners October 25, 2023 19:22
@bedevere-app bedevere-app Bot mentioned this pull request Oct 25, 2023
Counter-intuitive behavior of Server.close() / wait_closed() #79033
Closed
@bedevere-app bedevere-app Bot added the awaiting core review label Oct 25, 2023
@gvanrossum gvanrossum added the needs backport to 3.12 only security fixes label Oct 25, 2023
@gvanrossum

gvanrossum commented Oct 26, 2023

Copy link
Copy Markdown
Member Author

Maybe @graingert has some time to review? (I'll trade you -- I'm reviewing #110728 right now.)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Dreamsorcerer
Dreamsorcerer approved these changes Oct 26, 2023
View reviewed changes
@Dreamsorcerer Dreamsorcerer mentioned this pull request Oct 26, 2023
GH-79033: docs: Minor improvement to asyncio.Server.wait_closed() #111260
Closed
willingc
willingc approved these changes Oct 28, 2023
View reviewed changes

@willingc willingc left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @gvanrossum for the additional comments and clarification. I'm making one small docstring clarification and then will merge.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/asyncio/base_events.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels Oct 28, 2023
@willingc
Update Lib/asyncio/base_events.py
07751c4
@willingc
willingc enabled auto-merge (squash) October 28, 2023 17:36
gvanrossum
gvanrossum commented Oct 28, 2023
View reviewed changes

@gvanrossum gvanrossum left a comment

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

willingc reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@willingc
willingc merged commit 2655369 into python:main Oct 28, 2023
@miss-islington-app

miss-islington-app Bot commented Oct 28, 2023

Copy link
Copy Markdown

Thanks @gvanrossum for the PR, and @willingc for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label Oct 28, 2023
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Oct 28, 2023
@gvanrossum @willingc @miss-islington
pythongh-79033: Try to fix asyncio.Server.wait_closed() again (python…
9feb9e8
…GH-111336)

* Try to fix asyncio.Server.wait_closed() again

I identified the condition that `wait_closed()` is intended
to wait for: the server is closed *and* there are no more
active connections.

When this condition first becomes true, `_wakeup()` is called
(either from `close()` or from `_detach()`) and it sets `_waiters`
to `None`. So we just check for `self._waiters is None`; if it's
not `None`, we know we have to wait, and do so.

A problem was that the new test introduced in 3.12 explicitly
tested that `wait_closed()` returns immediately when the server
is *not* closed but there are currently no active connections.
This was a mistake (probably a misunderstanding of the intended
semantics). I've fixed the test, and added a separate test that
checks exactly for this scenario.

I also fixed an oddity where in `_wakeup()` the result of the
waiter was set to the waiter itself. This result is not used
anywhere and I changed this to `None`, to avoid a GC cycle.

* Update Lib/asyncio/base_events.py

---------

(cherry picked from commit 2655369)

Co-authored-by: Guido van Rossum <[email protected]>
Co-authored-by: Carol Willing <[email protected]>
@bedevere-app

bedevere-app Bot commented Oct 28, 2023

Copy link
Copy Markdown

GH-111424 is a backport of this pull request to the 3.12 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.12 only security fixes label Oct 28, 2023
willingc added a commit that referenced this pull request Oct 28, 2023
@miss-islington @gvanrossum @willingc
[3.12] gh-79033: Try to fix asyncio.Server.wait_closed() again (GH-11…
2e5d4e2
…1336) (#111424)

gh-79033: Try to fix asyncio.Server.wait_closed() again (GH-111336)

* Try to fix asyncio.Server.wait_closed() again

I identified the condition that `wait_closed()` is intended
to wait for: the server is closed *and* there are no more
active connections.

When this condition first becomes true, `_wakeup()` is called
(either from `close()` or from `_detach()`) and it sets `_waiters`
to `None`. So we just check for `self._waiters is None`; if it's
not `None`, we know we have to wait, and do so.

A problem was that the new test introduced in 3.12 explicitly
tested that `wait_closed()` returns immediately when the server
is *not* closed but there are currently no active connections.
This was a mistake (probably a misunderstanding of the intended
semantics). I've fixed the test, and added a separate test that
checks exactly for this scenario.

I also fixed an oddity where in `_wakeup()` the result of the
waiter was set to the waiter itself. This result is not used
anywhere and I changed this to `None`, to avoid a GC cycle.

* Update Lib/asyncio/base_events.py

---------

(cherry picked from commit 2655369)

Co-authored-by: Guido van Rossum <[email protected]>
Co-authored-by: Carol Willing <[email protected]>
iritkatriel pushed a commit to iritkatriel/cpython that referenced this pull request Oct 29, 2023
@gvanrossum @willingc @iritkatriel
pythongh-79033: Try to fix asyncio.Server.wait_closed() again (python…
c483c69
…GH-111336)

* Try to fix asyncio.Server.wait_closed() again

I identified the condition that `wait_closed()` is intended
to wait for: the server is closed *and* there are no more
active connections.

When this condition first becomes true, `_wakeup()` is called
(either from `close()` or from `_detach()`) and it sets `_waiters`
to `None`. So we just check for `self._waiters is None`; if it's
not `None`, we know we have to wait, and do so.

A problem was that the new test introduced in 3.12 explicitly
tested that `wait_closed()` returns immediately when the server
is *not* closed but there are currently no active connections.
This was a mistake (probably a misunderstanding of the intended
semantics). I've fixed the test, and added a separate test that
checks exactly for this scenario.

I also fixed an oddity where in `_wakeup()` the result of the
waiter was set to the waiter itself. This result is not used
anywhere and I changed this to `None`, to avoid a GC cycle.

* Update Lib/asyncio/base_events.py

---------

Co-authored-by: Carol Willing <[email protected]>
@gvanrossum
gvanrossum deleted the fix-wait-closed branch November 1, 2023 15:48
aisk pushed a commit to aisk/cpython that referenced this pull request Feb 11, 2024
@gvanrossum @willingc @aisk
pythongh-79033: Try to fix asyncio.Server.wait_closed() again (python…
80d7c8a
…GH-111336)

* Try to fix asyncio.Server.wait_closed() again

I identified the condition that `wait_closed()` is intended
to wait for: the server is closed *and* there are no more
active connections.

When this condition first becomes true, `_wakeup()` is called
(either from `close()` or from `_detach()`) and it sets `_waiters`
to `None`. So we just check for `self._waiters is None`; if it's
not `None`, we know we have to wait, and do so.

A problem was that the new test introduced in 3.12 explicitly
tested that `wait_closed()` returns immediately when the server
is *not* closed but there are currently no active connections.
This was a mistake (probably a misunderstanding of the intended
semantics). I've fixed the test, and added a separate test that
checks exactly for this scenario.

I also fixed an oddity where in `_wakeup()` the result of the
waiter was set to the waiter itself. This result is not used
anywhere and I changed this to `None`, to avoid a GC cycle.

* Update Lib/asyncio/base_events.py

---------

Co-authored-by: Carol Willing <[email protected]>
Glyphack pushed a commit to Glyphack/cpython that referenced this pull request Sep 2, 2024
@gvanrossum @willingc @Glyphack
pythongh-79033: Try to fix asyncio.Server.wait_closed() again (python…
a5c0ded
…GH-111336)

* Try to fix asyncio.Server.wait_closed() again

I identified the condition that `wait_closed()` is intended
to wait for: the server is closed *and* there are no more
active connections.

When this condition first becomes true, `_wakeup()` is called
(either from `close()` or from `_detach()`) and it sets `_waiters`
to `None`. So we just check for `self._waiters is None`; if it's
not `None`, we know we have to wait, and do so.

A problem was that the new test introduced in 3.12 explicitly
tested that `wait_closed()` returns immediately when the server
is *not* closed but there are currently no active connections.
This was a mistake (probably a misunderstanding of the intended
semantics). I've fixed the test, and added a separate test that
checks exactly for this scenario.

I also fixed an oddity where in `_wakeup()` the result of the
waiter was set to the waiter itself. This result is not used
anywhere and I changed this to `None`, to avoid a GC cycle.

* Update Lib/asyncio/base_events.py

---------

Co-authored-by: Carol Willing <[email protected]>
PeterD1524 added a commit to PeterD1524/symmetrical-doodle that referenced this pull request Dec 16, 2024
@PeterD1524
fix hang when closing adb reverse tunnel
258137b
According to python/cpython#111336, asyncio.Server.wait_closed is intended to wait for: the server is closed and there are no more active connections.
It should not wait for connections to finish when closing the adb reverse tunnel, so do not call wait_closed.

Signed-off-by: PeterD1524 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@willingc willingc willingc approved these changes
@1st1 1st1 Awaiting requested review from 1st1 1st1 is a code owner
@asvetlov asvetlov Awaiting requested review from asvetlov asvetlov is a code owner
@kumaraditya303 kumaraditya303 Awaiting requested review from kumaraditya303 kumaraditya303 is a code owner
+1 more reviewer
@Dreamsorcerer Dreamsorcerer Dreamsorcerer approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@gvanrossum @Dreamsorcerer @willingc
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.