Project

General

Profile

Actions

Feature #17357

open

`Queue#pop` should have a block form for closed queues

Added by marcandre (Marc-Andre Lafortune) over 3 years ago. Updated about 3 years ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:101171]

Description

It is currently difficult to reliably distinguish a nil value in a queue from the nil that is returned when a Queue is closed:

n = 100_000
result = []
t2 = Thread.new { n.times { Thread.pass }} # to make things less predictable
n.times.count do
  q = Queue.new
  t = Thread.new { q.pop; result << q.closed? }
  q << nil
  q.close
  t.join
end
puts result.count(true) # => some number usually > 9990 and < 10000

To be completely sure, one needs a Mutex or wrap/unwrap nil values.

Queue#pop should offer a surefire way to handle closed queues. I propose that an optional block be called in this case:

q = Queue.new.close
q.pop # => nil
q.pop { :closed }  # => :closed

Proposed PR: https://github.com/ruby/ruby/pull/3830


Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #10600: [PATCH] Queue#closeClosedko1 (Koichi Sasada)Actions
Actions #1

Updated by mame (Yusuke Endoh) over 3 years ago

Updated by naruse (Yui NARUSE) over 3 years ago

  • Status changed from Open to Feedback

Do you have a use case?

The issue is well discussed in [Feature #10600] and concluded as current spec.
To discuss again we need new materials.

Updated by marcandre (Marc-Andre Lafortune) over 3 years ago

  • Status changed from Feedback to Open

General use case: using Queue for objects that might be nil.

Why I opened this issue? I am writing a pure-Ruby backport of Ractor (using Thread). I am using Queue for messaging queues. nil can be value sent / received by Ractors (e.g. Ractor.yield). Can also be the final result of a ractor block. I need to store this in Queue.

So to be safe, I need to wrap/unwrap nil values.

My concern is same as with timeout: option: we have an "easy" way to do something that works 99%+ of the time, but is not 100% safe. Currently the only 100% way is difficult. People are lazy. We need to give easy 100% solution.

Updated by marcandre (Marc-Andre Lafortune) over 3 years ago

Final note:

  • no particular justification was given for choosing not to differentiate nil and closed result at the time.
  • many APIs were proposed (raising, or keyword parameters). Keyword parameters were a "no" because they were slow. I imagine that is no longer the case.

Let's make Ruby safe.

Updated by Dan0042 (Daniel DeLorme) over 3 years ago

If this is accepted I think it would be good to have the same API as Hash#fetch, with both argument and block forms. For consistency.

edit: oops, I didn't realize that Queue#pop already has a non_block optional argument.

Actions #6

Updated by znz (Kazuhiro NISHIYAMA) about 3 years ago

  • Subject changed from `Queue#pop` should have a block form for clsoed queues to `Queue#pop` should have a block form for closed queues
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0