File tree Expand file tree Collapse file tree 13 files changed +70
-50
lines changed
Expand file tree Collapse file tree 13 files changed +70
-50
lines changed Original file line number Diff line number Diff line change 1212
1313loop do
1414 Channel . select do |s |
15- s . take ( tick ) { print "tick.\n " }
15+ s . take ( tick ) { | t | print "tick.\n " if t }
1616 s . take ( boom ) do
1717 print "BOOM!\n "
1818 exit
Original file line number Diff line number Diff line change 1717
1818limiter = Channel . ticker ( 0.2 )
1919requests . each do |req |
20- ~limiter
21- print "request #{ req } #{ Channel ::Tick . new } \n "
20+ print "request #{ req } #{ Channel ::Tick . new } \n " if ~limiter
2221end
2322print "\n "
2423
2726 bursty_limiter << Channel ::Tick . new
2827end
2928
29+ ticker = Channel . ticker ( 0.2 )
3030Channel . go do
31- Channel . ticker ( 0.2 ) . each do |t |
31+ ticker . each do |t |
3232 bursty_limiter << t
3333 end
3434end
4444 print "request #{ req } #{ Channel ::Tick . new } \n "
4545end
4646
47+ limiter . close
48+ ticker . close
49+
4750__END__
4851request 1 2012-10-19 00:38:18.687438 +0000 UTC
4952request 2 2012-10-19 00:38:18.887471 +0000 UTC
Original file line number Diff line number Diff line change 1010ticker = Channel . ticker ( 0.5 )
1111Channel . go do
1212 ticker . each do |tick |
13- print "Tick at #{ tick } \n "
13+ print "Tick at #{ tick } \n " if tick
1414 end
1515end
1616
Original file line number Diff line number Diff line change 99
1010timer1 = Channel . timer ( 2 )
1111
12- ~timer1
13- puts 'Timer 1 expired'
12+ puts 'Timer 1 expired' if ~timer1
1413
1514timer2 = Channel . timer ( 1 )
1615Channel . go do
17- ~timer2
18- print "Timer 2 expired\n "
16+ print "Timer 2 expired\n " if ~timer2
1917end
2018
2119stop2 = timer2 . stop
Original file line number Diff line number Diff line change @@ -12,7 +12,7 @@ class Channel
1212 include Enumerable
1313
1414 # NOTE: Move to global IO pool once stable
15- GOROUTINES = Concurrent ::CachedThreadPool . new
15+ GOROUTINES = Concurrent ::CachedThreadPool . new ( auto_terminate : true )
1616 private_constant :GOROUTINES
1717
1818 BUFFER_TYPES = {
Original file line number Diff line number Diff line change 11require 'concurrent/synchronization/lockable_object'
2+ require 'concurrent/utility/at_exit'
23
34module Concurrent
45 class Channel
@@ -32,6 +33,7 @@ def initialize(*args)
3233 @capacity = 0
3334 @buffer = nil
3435 ns_initialize ( *args )
36+ AtExit . add ( self ) { terminate_at_exit }
3537 end
3638 end
3739
@@ -232,6 +234,11 @@ def ns_full?
232234 def ns_closed?
233235 @closed
234236 end
237+
238+ # @!visibility private
239+ def terminate_at_exit
240+ synchronize { self . closed = true }
241+ end
235242 end
236243 end
237244 end
Original file line number Diff line number Diff line change @@ -19,12 +19,14 @@ def ns_initialize(interval)
1919
2020 def do_poll
2121 synchronize do
22- if !ns_closed? && ( now = Concurrent . monotonic_time ) >= @next_tick
22+ if ns_closed?
23+ return Concurrent ::NULL , false
24+ elsif ( now = Concurrent . monotonic_time ) >= @next_tick
2325 tick = Concurrent ::Channel ::Tick . new ( @next_tick )
2426 @next_tick = now + @interval
25- return tick
27+ return tick , true
2628 else
27- return Concurrent :: NULL
29+ return nil , true
2830 end
2931 end
3032 end
Original file line number Diff line number Diff line change @@ -18,26 +18,28 @@ def offer(item)
1818 end
1919
2020 def take
21- # a Go timer will block forever if stopped
2221 loop do
23- tick = do_poll
24- return tick if tick != Concurrent ::NULL
25- Thread . pass
22+ tick , _ = do_poll
23+ if tick
24+ return tick
25+ else
26+ Thread . pass
27+ end
2628 end
2729 end
2830
2931 def next
30- # a Go timer will block forever if stopped
31- # it will always return `true` for more
3232 loop do
33- tick = do_poll
34- return tick , true if tick != Concurrent :: NULL
33+ tick , more = do_poll
34+ return tick , more if tick
3535 Thread . pass
3636 end
3737 end
3838
3939 def poll
40- do_poll
40+ tick , _ = do_poll
41+ tick = Concurrent ::NULL unless tick
42+ tick
4143 end
4244
4345 private
@@ -61,12 +63,14 @@ def ns_full?
6163
6264 def do_poll
6365 synchronize do
64- if !ns_closed? && Concurrent . monotonic_time >= @tick
66+ if ns_closed?
67+ return Concurrent ::NULL , false
68+ elsif Concurrent . monotonic_time >= @tick
6569 # only one listener gets notified
6670 self . closed = true
67- return Concurrent ::Channel ::Tick . new ( @tick )
71+ return Concurrent ::Channel ::Tick . new ( @tick ) , false
6872 else
69- return Concurrent :: NULL
73+ return nil , true
7074 end
7175 end
7276 end
Original file line number Diff line number Diff line change @@ -16,6 +16,13 @@ module Concurrent::Channel::Buffer
1616 expected . times { actual += 1 if subject . take . is_a? Concurrent ::Channel ::Tick }
1717 expect ( actual ) . to eq expected
1818 end
19+
20+ it 'returns Concurrent::NULL when closed after trigger' do
21+ subject . take
22+ subject . close
23+ expect ( subject ) . to be_closed
24+ expect ( subject . take ) . to eq Concurrent ::NULL
25+ end
1926 end
2027
2128 context '#poll' do
@@ -37,6 +44,17 @@ module Concurrent::Channel::Buffer
3744 expected . times { actual += 1 if subject . next . first . is_a? Concurrent ::Channel ::Tick }
3845 expect ( actual ) . to eq expected
3946 end
47+
48+ it 'returns true for more while open' do
49+ _ , more = subject . next
50+ expect ( more ) . to be true
51+ end
52+
53+ it 'returns false for more once closed' do
54+ subject . close
55+ _ , more = subject . next
56+ expect ( more ) . to be false
57+ end
4058 end
4159 end
4260end
Original file line number Diff line number Diff line change @@ -33,6 +33,11 @@ module Concurrent::Channel::Buffer
3333 end
3434 expect ( subject ) . to be_closed
3535 end
36+
37+ it 'returns false for more' do
38+ _ , more = subject . next
39+ expect ( more ) . to be false
40+ end
3641 end
3742 end
3843end
You can’t perform that action at this time.
0 commit comments