[#68478] Looking for MRI projects for Ruby Google Summer of Code 2015 — Tony Arcieri <bascule@...>

Hi ruby-core,

10 messages 2015/03/10

[ruby-core:68642] [Ruby trunk - Feature #10600] [PATCH] Queue#close

From: john@...
Date: 2015-03-25 19:31:44 UTC
List: ruby-core #68642
Issue #10600 has been updated by John Anderson.

File queue_benchmark.rb added

Some performance numbers, using the attached benchmark script:

~~~

$ ruby queue_benchmark.rb 100000
RUBY_DESCRIPTION: ruby 2.3.0dev (2015-03-25 trunk 50089) [x86_64-linux]
Queue#close: no
                                                         user     system      total        real
01 producer 01 consumer                              2.230000   0.110000   2.340000 (  2.219983)
01 producer 02 consumer                              2.360000   0.170000   2.530000 (  2.348708)
01 producer 99 consumer                              9.450000   5.290000  14.740000 ( 10.081818)
02 producer 01 consumer                              2.420000   0.080000   2.500000 (  2.348568)
99 producer 01 consumer                              6.850000   3.940000  10.790000 (  7.464203)


$ ruby queue_benchmark.rb 100000
RUBY_DESCRIPTION: ruby 2.3.0dev (2015-03-25 queue-close 50089) [x86_64-linux]
Queue#close: yes
                                                         user     system      total        real
01 producer 01 consumer                              2.380000   0.120000   2.500000 (  2.368862)
01 producer 02 consumer                              2.460000   0.170000   2.630000 (  2.460940)
01 producer 99 consumer                              9.420000   5.350000  14.770000 ( 10.075400)
02 producer 01 consumer                              2.970000   0.130000   3.100000 (  2.894214)
99 producer 01 consumer                              7.050000   4.100000  11.150000 (  7.676364)
~~~


----------------------------------------
Feature #10600: [PATCH] Queue#close
https://bugs.ruby-lang.org/issues/10600#change-51940

* Author: John Anderson
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
In a multiple-producer / multiple-consumer situation using blocking enq and deq, closing a queue cleanly is difficult. It's possible using a queue poison token, but unpleasant because either producers have to know how to match up number of poison tokens with number of consumers, or consumers have to keep putting the poison back into the queue which complicates testing for empty and not blocking on deq.

This patch (from trunk at b2a128f) implements Queue#close which will close the queue to producers, leaving consumers to deq the remaining items. Once the queue is both closed and empty, consumers will not block. When an empty queue is closed, all consumers blocking on deq will be woken up and given nil.

With Queue#close, clean queue shutdown is simple:

~~~ ruby
queue = SizedQueue.new 1000

consumer_threads = lots_of.times.map do
  Thread.new do
    while item = queue.pop
      do_work item
    end
  end
end

source = somewhat_async_enumerator

producer_threads = a_few.times.map do
  Thread.new do
    loop{queue << source.next}
  end
end

producer_threads.each &:join
queue.close
consumer_threads.each &:join
~~~


---Files--------------------------------
queue-close.diff (5.18 KB)
queue-close-2.diff (10.2 KB)
patch-25f99aef.diff (25.2 KB)
queue_benchmark.rb (2.95 KB)


-- 
https://bugs.ruby-lang.org/

In This Thread

Prev Next