concurrent-ruby 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -21
  3. data/README.md +276 -275
  4. data/lib/concurrent.rb +28 -28
  5. data/lib/concurrent/agent.rb +114 -114
  6. data/lib/concurrent/cached_thread_pool.rb +131 -131
  7. data/lib/concurrent/defer.rb +65 -65
  8. data/lib/concurrent/event.rb +60 -60
  9. data/lib/concurrent/event_machine_defer_proxy.rb +23 -23
  10. data/lib/concurrent/executor.rb +96 -96
  11. data/lib/concurrent/fixed_thread_pool.rb +99 -99
  12. data/lib/concurrent/functions.rb +120 -120
  13. data/lib/concurrent/future.rb +42 -42
  14. data/lib/concurrent/global_thread_pool.rb +24 -16
  15. data/lib/concurrent/goroutine.rb +29 -29
  16. data/lib/concurrent/null_thread_pool.rb +22 -22
  17. data/lib/concurrent/obligation.rb +67 -67
  18. data/lib/concurrent/promise.rb +174 -174
  19. data/lib/concurrent/reactor.rb +166 -166
  20. data/lib/concurrent/reactor/drb_async_demux.rb +83 -83
  21. data/lib/concurrent/reactor/tcp_sync_demux.rb +131 -131
  22. data/lib/concurrent/supervisor.rb +105 -105
  23. data/lib/concurrent/thread_pool.rb +76 -76
  24. data/lib/concurrent/utilities.rb +32 -32
  25. data/lib/concurrent/version.rb +3 -3
  26. data/lib/concurrent_ruby.rb +1 -1
  27. data/md/agent.md +123 -123
  28. data/md/defer.md +174 -174
  29. data/md/event.md +32 -32
  30. data/md/executor.md +187 -187
  31. data/md/future.md +83 -83
  32. data/md/goroutine.md +52 -52
  33. data/md/obligation.md +32 -32
  34. data/md/promise.md +227 -227
  35. data/md/thread_pool.md +224 -224
  36. data/spec/concurrent/agent_spec.rb +390 -386
  37. data/spec/concurrent/cached_thread_pool_spec.rb +125 -125
  38. data/spec/concurrent/defer_spec.rb +199 -195
  39. data/spec/concurrent/event_machine_defer_proxy_spec.rb +256 -256
  40. data/spec/concurrent/event_spec.rb +134 -134
  41. data/spec/concurrent/executor_spec.rb +200 -200
  42. data/spec/concurrent/fixed_thread_pool_spec.rb +83 -83
  43. data/spec/concurrent/functions_spec.rb +217 -217
  44. data/spec/concurrent/future_spec.rb +112 -108
  45. data/spec/concurrent/global_thread_pool_spec.rb +11 -38
  46. data/spec/concurrent/goroutine_spec.rb +67 -67
  47. data/spec/concurrent/null_thread_pool_spec.rb +57 -57
  48. data/spec/concurrent/obligation_shared.rb +132 -132
  49. data/spec/concurrent/promise_spec.rb +316 -312
  50. data/spec/concurrent/reactor/drb_async_demux_spec.rb +196 -196
  51. data/spec/concurrent/reactor/tcp_sync_demux_spec.rb +410 -410
  52. data/spec/concurrent/reactor_spec.rb +364 -364
  53. data/spec/concurrent/supervisor_spec.rb +269 -269
  54. data/spec/concurrent/thread_pool_shared.rb +204 -204
  55. data/spec/concurrent/uses_global_thread_pool_shared.rb +64 -0
  56. data/spec/concurrent/utilities_spec.rb +74 -74
  57. data/spec/spec_helper.rb +32 -32
  58. metadata +17 -19
@@ -1,108 +1,112 @@
1
- require 'spec_helper'
2
- require_relative 'obligation_shared'
3
-
4
- module Concurrent
5
-
6
- describe Future do
7
-
8
- let!(:fulfilled_value) { 10 }
9
- let!(:rejected_reason) { StandardError.new('mojo jojo') }
10
-
11
- let(:pending_subject) do
12
- Future.new{ sleep(3); fulfilled_value }
13
- end
14
-
15
- let(:fulfilled_subject) do
16
- Future.new{ fulfilled_value }.tap(){ sleep(0.1) }
17
- end
18
-
19
- let(:rejected_subject) do
20
- Future.new{ raise rejected_reason }.tap(){ sleep(0.1) }
21
- end
22
-
23
- before(:each) do
24
- Future.thread_pool = FixedThreadPool.new(1)
25
- end
26
-
27
- it_should_behave_like Concurrent::Obligation
28
-
29
- context 'behavior' do
30
-
31
- it 'implements :future behavior' do
32
- lambda {
33
- Future.new{ nil }
34
- }.should_not raise_error
35
-
36
- Future.new{ nil }.behaves_as?(:future).should be_true
37
- end
38
- end
39
-
40
- context '#initialize' do
41
-
42
- it 'spawns a new thread when a block is given' do
43
- Future.thread_pool.should_receive(:post).once.with(any_args())
44
- Future.new{ nil }
45
- end
46
-
47
- it 'does not spawns a new thread when no block given' do
48
- Thread.should_not_receive(:new).with(any_args())
49
- Future.new
50
- end
51
-
52
- it 'immediately sets the state to :fulfilled when no block given' do
53
- Future.new.should be_fulfilled
54
- end
55
-
56
- it 'immediately sets the value to nil when no block given' do
57
- Future.new.value.should be_nil
58
- end
59
- end
60
-
61
- context 'fulfillment' do
62
-
63
- it 'passes all arguments to handler' do
64
- @a = @b = @c = nil
65
- f = Future.new(1, 2, 3) do |a, b, c|
66
- @a, @b, @c = a, b, c
67
- end
68
- sleep(0.1)
69
- [@a, @b, @c].should eq [1, 2, 3]
70
- end
71
-
72
- it 'sets the value to the result of the handler' do
73
- f = Future.new(10){|a| a * 2 }
74
- sleep(0.1)
75
- f.value.should eq 20
76
- end
77
-
78
- it 'sets the state to :fulfilled when the block completes' do
79
- f = Future.new(10){|a| a * 2 }
80
- sleep(0.1)
81
- f.should be_fulfilled
82
- end
83
-
84
- it 'sets the value to nil when the handler raises an exception' do
85
- f = Future.new{ raise StandardError }
86
- sleep(0.1)
87
- f.value.should be_nil
88
- end
89
-
90
- it 'sets the state to :rejected when the handler raises an exception' do
91
- f = Future.new{ raise StandardError }
92
- sleep(0.1)
93
- f.should be_rejected
94
- end
95
-
96
- context 'aliases' do
97
-
98
- it 'aliases #realized? for #fulfilled?' do
99
- fulfilled_subject.should be_realized
100
- end
101
-
102
- it 'aliases #deref for #value' do
103
- fulfilled_subject.deref.should eq fulfilled_value
104
- end
105
- end
106
- end
107
- end
108
- end
1
+ require 'spec_helper'
2
+ require_relative 'obligation_shared'
3
+ require_relative 'uses_global_thread_pool_shared'
4
+
5
+ module Concurrent
6
+
7
+ describe Future do
8
+
9
+ let!(:thread_pool_user){ Future }
10
+ it_should_behave_like Concurrent::UsesGlobalThreadPool
11
+
12
+ let!(:fulfilled_value) { 10 }
13
+ let!(:rejected_reason) { StandardError.new('mojo jojo') }
14
+
15
+ let(:pending_subject) do
16
+ Future.new{ sleep(3); fulfilled_value }
17
+ end
18
+
19
+ let(:fulfilled_subject) do
20
+ Future.new{ fulfilled_value }.tap(){ sleep(0.1) }
21
+ end
22
+
23
+ let(:rejected_subject) do
24
+ Future.new{ raise rejected_reason }.tap(){ sleep(0.1) }
25
+ end
26
+
27
+ before(:each) do
28
+ Future.thread_pool = FixedThreadPool.new(1)
29
+ end
30
+
31
+ it_should_behave_like Concurrent::Obligation
32
+
33
+ context 'behavior' do
34
+
35
+ it 'implements :future behavior' do
36
+ lambda {
37
+ Future.new{ nil }
38
+ }.should_not raise_error
39
+
40
+ Future.new{ nil }.behaves_as?(:future).should be_true
41
+ end
42
+ end
43
+
44
+ context '#initialize' do
45
+
46
+ it 'spawns a new thread when a block is given' do
47
+ Future.thread_pool.should_receive(:post).once.with(any_args())
48
+ Future.new{ nil }
49
+ end
50
+
51
+ it 'does not spawns a new thread when no block given' do
52
+ Thread.should_not_receive(:new).with(any_args())
53
+ Future.new
54
+ end
55
+
56
+ it 'immediately sets the state to :fulfilled when no block given' do
57
+ Future.new.should be_fulfilled
58
+ end
59
+
60
+ it 'immediately sets the value to nil when no block given' do
61
+ Future.new.value.should be_nil
62
+ end
63
+ end
64
+
65
+ context 'fulfillment' do
66
+
67
+ it 'passes all arguments to handler' do
68
+ @a = @b = @c = nil
69
+ f = Future.new(1, 2, 3) do |a, b, c|
70
+ @a, @b, @c = a, b, c
71
+ end
72
+ sleep(0.1)
73
+ [@a, @b, @c].should eq [1, 2, 3]
74
+ end
75
+
76
+ it 'sets the value to the result of the handler' do
77
+ f = Future.new(10){|a| a * 2 }
78
+ sleep(0.1)
79
+ f.value.should eq 20
80
+ end
81
+
82
+ it 'sets the state to :fulfilled when the block completes' do
83
+ f = Future.new(10){|a| a * 2 }
84
+ sleep(0.1)
85
+ f.should be_fulfilled
86
+ end
87
+
88
+ it 'sets the value to nil when the handler raises an exception' do
89
+ f = Future.new{ raise StandardError }
90
+ sleep(0.1)
91
+ f.value.should be_nil
92
+ end
93
+
94
+ it 'sets the state to :rejected when the handler raises an exception' do
95
+ f = Future.new{ raise StandardError }
96
+ sleep(0.1)
97
+ f.should be_rejected
98
+ end
99
+
100
+ context 'aliases' do
101
+
102
+ it 'aliases #realized? for #fulfilled?' do
103
+ fulfilled_subject.should be_realized
104
+ end
105
+
106
+ it 'aliases #deref for #value' do
107
+ fulfilled_subject.deref.should eq fulfilled_value
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -1,38 +1,11 @@
1
- require 'spec_helper'
2
-
3
- module Concurrent
4
-
5
- describe UsesGlobalThreadPool do
6
-
7
- before(:each) do
8
- $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
9
- end
10
-
11
- it 'defaults to the global thread pool' do
12
- clazz = Class.new{ include UsesGlobalThreadPool }
13
- clazz.thread_pool.should eq $GLOBAL_THREAD_POOL
14
- end
15
-
16
- it 'sets and gets the thread pool for the class' do
17
- pool = NullThreadPool.new
18
- clazz = Class.new{ include UsesGlobalThreadPool }
19
-
20
- clazz.thread_pool = pool
21
- clazz.thread_pool.should eq pool
22
- end
23
-
24
- it 'gives each class its own thread pool' do
25
- clazz1 = Class.new{ include UsesGlobalThreadPool }
26
- clazz2 = Class.new{ include UsesGlobalThreadPool }
27
- clazz3 = Class.new{ include UsesGlobalThreadPool }
28
-
29
- clazz1.thread_pool = FixedThreadPool.new(1)
30
- clazz2.thread_pool = CachedThreadPool.new
31
- clazz3.thread_pool = NullThreadPool.new
32
-
33
- clazz1.thread_pool.should_not eq clazz2.thread_pool
34
- clazz2.thread_pool.should_not eq clazz3.thread_pool
35
- clazz3.thread_pool.should_not eq clazz1.thread_pool
36
- end
37
- end
38
- end
1
+ require 'spec_helper'
2
+ require_relative 'uses_global_thread_pool_shared'
3
+
4
+ module Concurrent
5
+
6
+ describe UsesGlobalThreadPool do
7
+
8
+ let!(:thread_pool_user){ Class.new{ include UsesGlobalThreadPool } }
9
+ it_should_behave_like Concurrent::UsesGlobalThreadPool
10
+ end
11
+ end
@@ -1,67 +1,67 @@
1
- require 'spec_helper'
2
-
3
- module Concurrent
4
-
5
- describe '#go' do
6
-
7
- before(:each) do
8
- $GLOBAL_THREAD_POOL = CachedThreadPool.new
9
- end
10
-
11
- it 'passes all arguments to the block' do
12
- @expected = nil
13
- go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
14
- sleep(0.1)
15
- @expected.should eq [3, 2, 1]
16
- end
17
-
18
- it 'returns true if the thread is successfully created' do
19
- $GLOBAL_THREAD_POOL.should_receive(:post).and_return(true)
20
- go{ nil }.should be_true
21
- end
22
-
23
- it 'returns false if the thread cannot be created' do
24
- $GLOBAL_THREAD_POOL.should_receive(:post).and_return(false)
25
- go{ nil }.should be_false
26
- end
27
-
28
- it 'immediately returns false if no block is given' do
29
- go().should be_false
30
- end
31
-
32
- it 'does not create a thread if no block is given' do
33
- $GLOBAL_THREAD_POOL.should_not_receive(:post)
34
- go()
35
- sleep(0.1)
36
- end
37
-
38
- it 'supresses exceptions on the thread' do
39
- lambda{
40
- go{ raise StandardError }
41
- sleep(0.1)
42
- }.should_not raise_error
43
- end
44
-
45
- it 'processes the block' do
46
- @expected = false
47
- go(1,2,3){|*args| @expected = args }
48
- sleep(0.1)
49
- @expected.should eq [1,2,3]
50
- end
51
-
52
- it 'accepts an alternate thread pool as the first argument' do
53
- pool = Concurrent::FixedThreadPool.new(2)
54
- pool.should_receive(:post).with(no_args())
55
- go(pool){ sleep(0.1) }
56
- sleep(0.2)
57
- end
58
-
59
- it 'passes all other arguments to the block when a thread pool is given' do
60
- @expected = nil
61
- pool = Concurrent::FixedThreadPool.new(2)
62
- go(pool, 1, 2, 3){|a, b, c| @expected = [c, b, a] }
63
- sleep(0.1)
64
- @expected.should eq [3, 2, 1]
65
- end
66
- end
67
- end
1
+ require 'spec_helper'
2
+
3
+ module Concurrent
4
+
5
+ describe '#go' do
6
+
7
+ before(:each) do
8
+ $GLOBAL_THREAD_POOL = CachedThreadPool.new
9
+ end
10
+
11
+ it 'passes all arguments to the block' do
12
+ @expected = nil
13
+ go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
14
+ sleep(0.1)
15
+ @expected.should eq [3, 2, 1]
16
+ end
17
+
18
+ it 'returns true if the thread is successfully created' do
19
+ $GLOBAL_THREAD_POOL.should_receive(:post).and_return(true)
20
+ go{ nil }.should be_true
21
+ end
22
+
23
+ it 'returns false if the thread cannot be created' do
24
+ $GLOBAL_THREAD_POOL.should_receive(:post).and_return(false)
25
+ go{ nil }.should be_false
26
+ end
27
+
28
+ it 'immediately returns false if no block is given' do
29
+ go().should be_false
30
+ end
31
+
32
+ it 'does not create a thread if no block is given' do
33
+ $GLOBAL_THREAD_POOL.should_not_receive(:post)
34
+ go()
35
+ sleep(0.1)
36
+ end
37
+
38
+ it 'supresses exceptions on the thread' do
39
+ lambda{
40
+ go{ raise StandardError }
41
+ sleep(0.1)
42
+ }.should_not raise_error
43
+ end
44
+
45
+ it 'processes the block' do
46
+ @expected = false
47
+ go(1,2,3){|*args| @expected = args }
48
+ sleep(0.1)
49
+ @expected.should eq [1,2,3]
50
+ end
51
+
52
+ it 'accepts an alternate thread pool as the first argument' do
53
+ pool = Concurrent::FixedThreadPool.new(2)
54
+ pool.should_receive(:post).with(no_args())
55
+ go(pool){ sleep(0.1) }
56
+ sleep(0.2)
57
+ end
58
+
59
+ it 'passes all other arguments to the block when a thread pool is given' do
60
+ @expected = nil
61
+ pool = Concurrent::FixedThreadPool.new(2)
62
+ go(pool, 1, 2, 3){|a, b, c| @expected = [c, b, a] }
63
+ sleep(0.1)
64
+ @expected.should eq [3, 2, 1]
65
+ end
66
+ end
67
+ end
@@ -1,57 +1,57 @@
1
- require 'spec_helper'
2
-
3
- require 'concurrent/goroutine'
4
-
5
- module Concurrent
6
-
7
- describe NullThreadPool do
8
-
9
- subject { NullThreadPool.new }
10
-
11
- after(:all) do
12
- $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
13
- end
14
-
15
- context '#post' do
16
-
17
- it 'proxies a call without arguments' do
18
- thread = Thread.new{ nil }
19
- Thread.should_receive(:new).with(no_args()).and_return(thread)
20
- $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
21
- subject.post{ nil }
22
- end
23
-
24
- it 'proxies a call with arguments' do
25
- thread = Thread.new{ nil }
26
- Thread.should_receive(:new).with(1,2,3).and_return(thread)
27
- $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
28
- subject.post(1,2,3){ nil }
29
- end
30
-
31
- it 'aliases #<<' do
32
- thread = Thread.new{ nil }
33
- Thread.should_receive(:new).with(no_args()).and_return(thread)
34
- $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
35
- subject << proc{ nil }
36
- end
37
- end
38
-
39
- context 'operation' do
40
-
41
- context 'goroutine' do
42
-
43
- it 'gets a new thread' do
44
- $GLOBAL_THREAD_POOL = subject
45
-
46
- t = Thread.new{ nil }
47
-
48
- Thread.should_receive(:new).with(no_args()).and_return(t)
49
- go{ nil }
50
-
51
- Thread.should_receive(:new).with(1,2,3).and_return(t)
52
- go(1,2,3){ nil }
53
- end
54
- end
55
- end
56
- end
57
- end
1
+ require 'spec_helper'
2
+
3
+ require 'concurrent/goroutine'
4
+
5
+ module Concurrent
6
+
7
+ describe NullThreadPool do
8
+
9
+ subject { NullThreadPool.new }
10
+
11
+ after(:all) do
12
+ $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
13
+ end
14
+
15
+ context '#post' do
16
+
17
+ it 'proxies a call without arguments' do
18
+ thread = Thread.new{ nil }
19
+ Thread.should_receive(:new).with(no_args()).and_return(thread)
20
+ $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
21
+ subject.post{ nil }
22
+ end
23
+
24
+ it 'proxies a call with arguments' do
25
+ thread = Thread.new{ nil }
26
+ Thread.should_receive(:new).with(1,2,3).and_return(thread)
27
+ $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
28
+ subject.post(1,2,3){ nil }
29
+ end
30
+
31
+ it 'aliases #<<' do
32
+ thread = Thread.new{ nil }
33
+ Thread.should_receive(:new).with(no_args()).and_return(thread)
34
+ $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
35
+ subject << proc{ nil }
36
+ end
37
+ end
38
+
39
+ context 'operation' do
40
+
41
+ context 'goroutine' do
42
+
43
+ it 'gets a new thread' do
44
+ $GLOBAL_THREAD_POOL = subject
45
+
46
+ t = Thread.new{ nil }
47
+
48
+ Thread.should_receive(:new).with(no_args()).and_return(t)
49
+ go{ nil }
50
+
51
+ Thread.should_receive(:new).with(1,2,3).and_return(t)
52
+ go(1,2,3){ nil }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end