Skip to content

bpo-37334: Add a cancel method to asyncio Queues #14227

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

Closed
wants to merge 7 commits into from

Conversation

tecki
Copy link
Contributor

@tecki tecki commented Jun 19, 2019

When working with queues, it is not uncommon that at some point the producer stops producing data for good, or the consumer stops consuming, for example because a network connection broke down or some user simply closed the session.

In this situation it is very useful to simply cancel all the waiting getters and putters. A simple method can do that, Queue.close.

https://bugs.python.org/issue37334

@mangrisano
Copy link
Contributor

/cc @asvetlov @1st1

@asvetlov
Copy link
Contributor

Do you want to allow calling queue.close() multiple times?
Call get() / put() after close()?

@tecki
Copy link
Contributor Author

tecki commented Jun 24, 2019

While I think it does not make much sense, I do not see a good reason to forbid calling close several times. You can also call cancel several times on a future. Also I do not think we should forbid calling get or put after a close. We would have to artificially add some flags.
Currently, what close does is pretty simple: it cancels all waiting getters and putters. Not more, not less. I think users will be happy to have this very simple interface, as then they know what's going on.

@asvetlov
Copy link
Contributor

I think the proposal makes the queues API more error-prone: concurrent put() and close() produces unpredictable result on get() side.

@1st1 we need your opinion here.

@tecki
Copy link
Contributor Author

tecki commented Nov 21, 2019

I think the proposal makes the queues API more error-prone: concurrent put() and close() produces unpredictable result on get() side.

Is that so? I am not aware of such a behavior, but if there is one, I'm happy to fix it. Could you give an example?

@jpetkau
Copy link

jpetkau commented Jul 10, 2020

@tecki Also I do not think we should forbid calling get or put after a close. We would have to artificially add some flags.
Currently, what close does is pretty simple: it cancels all waiting getters and putters. Not more, not less.

What about a consumers or producers doing something like:

async def consumer(queue):
    while not_done:
      job = await queue.get()
      result = await do_stuff(job)

async def producer(queue):
    while not_done:
      job = await make_job()
      await queue.put(job)

(This is the actual case I had, that led me to wish queues had cancellation, that led me to this issue).

In either case, they may not be waiting on the queue itself at the moment close (or cancel) is called, but they should still be shut down. Semantically, I think it makes the most sense of close means: "no more items can be put on this queue, so trying to do so raises an exception, and trying to get once the queue is empty also raises an exception."

@tecki
Copy link
Contributor Author

tecki commented May 12, 2021

@jpetkau your case can actually be solved pretty easily by setting your not_done variable to False once you cancel/close the queue. Sure, this feature could also be added to the cancel/close itself, but I am not sure whether it is worth the additional complexity in the standard library vs. additional work for users.

So, I would add this "close is close forever" functionality if there is a general agreement about it, but if not I would rather let it be as it is.

This PR has been open for almost two years now, it would be cool if it could be finished...

@gvanrossum
Copy link
Member

I propose to close this in favor of a shutdown() method with slightly different behavior -- it would allow the readers to continue draining the queue until it is empty. It would still stop writers whenever they attempt to write (put).

@gvanrossum gvanrossum closed this Aug 28, 2022
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.

8 participants