Skip to content

gh-102983: queue.Queue - Adding Cancelling Support #102996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

mementum
Copy link

@mementum mementum commented Mar 24, 2023

@mementum mementum requested a review from rhettinger as a code owner March 24, 2023 09:21
@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@mementum mementum marked this pull request as draft March 24, 2023 13:26
Lib/queue.py Outdated
Comment on lines 28 to 29
class Cancelled(Exception):
'Exception raised by Queue.get(block=True) when cancelled'
Copy link
Contributor

Choose a reason for hiding this comment

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

The pass is redundant and docstrings should be triple quoted:)

Suggested change
class Cancelled(Exception):
'Exception raised by Queue.get(block=True) when cancelled'
class Cancelled(Exception):
'''Exception raised by Queue.get(block=True) when cancelled'''

Copy link
Author

Choose a reason for hiding this comment

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

Indeed, I simply wanted to keep the same style with which the Full exception is written, just a couple of lines above.

cpython/Lib/queue.py

Lines 23 to 25 in f2e5a6e

class Full(Exception):
'Exception raised by Queue.put(block=0)/put_nowait().'
pass

Question:

  • Shall we add also the same changes to Full?

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
class Cancelled(Exception):
'Exception raised by Queue.get(block=True) when cancelled'
class Cancelled(Exception):
"""Exception raised by Queue.get(block=True) when cancelled."""

Furthermore, while we're at it, per PEP 257 (PEP-257) and widespread convention, docstrings must use triple double quotes and summary lines should be complete sentences that always end with a period.

@mementum
Copy link
Author

This PR already "works" (see sample test script in #102983. Things which could be considered

  • What happens if the user does cancel(n) where n > number of blocking get?

    If one looks at the implementation of the similar notify(n) in threading.Condition, the code would actually block waiting for new waiters on the Condition, so it would seem it is the programmer's responsibility to ensure that n <= number of blocking get to leave no pending cancellation.

  • If one leaves pending cancellations in place, should they also be applied to incoming non-blocking calls of get?

    One could even call this ahead of time cancellations

To fully avoid having pending cancellations in any case, the current amount of (blocking) gets can be considered in cancel(n) to be the maximum to cancel.

def cancel(self, n=1):
    with self.not_empty:
        n = min(n, len(self.not_empty._waiters))
        self.cancelling.release(n=n)
        self.not_empty.notify(n=n)

It would then depart from the similar behavior of notify behavior but would ensure only the actual blocking get are cancelled.

@rhettinger rhettinger removed their request for review March 26, 2023 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants