deadqueue icon indicating copy to clipboard operation
deadqueue copied to clipboard

Async functions to await a full or empty queue

Open overhacked opened this issue 4 years ago • 2 comments

Allow awaiting a full or empty queue.

  • Queue.empty() is useful for chaining futures in a multi-threaded program when some subsequent action, like a verification step, needs to be taken once the queue is emptied.
  • Queue.full() can help manage backpressure so that an autoscaling system can monitor when the queue fills before it starts increasing the number of workers.

overhacked avatar Mar 11 '22 16:03 overhacked

If you were to change the deadqueue::atomic::Available implementation so it returns the new (or old) value after add and sub you could use that to find out if the queue is full and/or empty. That way you could avoid calling available_permits and remove one possible race condition where the queue is empty for the fraction of a second but Semaphore::available_permits doesn't show that because of concurrent push/pop calls.

Even then you might miss an empty/full event, but it's less likely to happen than calling into Semaphore::available_permits outside of any atomic guarantees.

bikeshedder avatar Mar 18 '22 14:03 bikeshedder

Hi, read all these comments. Thanks for the feedback! Trying to find time to rework the PR accordingly.

overhacked avatar Mar 22 '22 15:03 overhacked

Finally circled back to this and updated the wait_full() and wait_empty() to use atomics instead of Semaphore::available_permits(). Thanks for your patience and not closing the PR.

overhacked avatar Jul 28 '23 17:07 overhacked

Sorry for taking so long. I completely forgot about that PR. :see_no_evil:

After reviewing it I only found two small details:

  1. Every time you use Available:add you add 1 to the previous value to see if the capacity has been reached. I'd rather change that code so the Available:add function already returns the new value so this comparison doesn't need to happen. The same can be done for Available::sub where comparing the new value against 0 is much clearer than comparing the previous value against 1.

  2. It would be nice if there was a way to get a hold of the watch channel of full and empty. That way an application that wants to perform some task every time the queue is full or empty doesn't need to continuously recreate the channel receiver.

If you happen to find time to look into that I'll wait a bit. I'm just as happy to merge this PR without those changes.

bikeshedder avatar Nov 09 '23 12:11 bikeshedder

Oh, and please explain this comment to me...

  • https://github.com/bikeshedder/deadqueue/pull/4/files#r1387924883

How is it borrowed mutably? :thinking:

bikeshedder avatar Nov 09 '23 12:11 bikeshedder

I should be able to look at these this weekend. Thanks!

overhacked avatar Nov 09 '23 21:11 overhacked

@overhacked Any updates on this PR?

bikeshedder avatar Jan 08 '24 09:01 bikeshedder

Requested changes pushed. Sorry I lost track of wrapping this up in the last few months of the year. Nothing going on in November or December... nothing else at all. :wink:

Thanks for your patience and support with this!

overhacked avatar Jan 09 '24 17:01 overhacked

Thanks a lot. Awesome work! :tada:

bikeshedder avatar Jan 10 '24 14:01 bikeshedder