concurrent-ruby 0.1.1.pre.5 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -48
  3. data/lib/concurrent.rb +0 -6
  4. data/lib/concurrent/agent.rb +40 -19
  5. data/lib/concurrent/cached_thread_pool.rb +11 -10
  6. data/lib/concurrent/defer.rb +12 -8
  7. data/lib/concurrent/fixed_thread_pool.rb +6 -12
  8. data/lib/concurrent/future.rb +20 -8
  9. data/lib/concurrent/global_thread_pool.rb +0 -13
  10. data/lib/concurrent/goroutine.rb +1 -5
  11. data/lib/concurrent/obligation.rb +64 -10
  12. data/lib/concurrent/promise.rb +60 -38
  13. data/lib/concurrent/thread_pool.rb +5 -16
  14. data/lib/concurrent/utilities.rb +0 -8
  15. data/lib/concurrent/version.rb +1 -1
  16. data/md/defer.md +4 -4
  17. data/md/promise.md +0 -2
  18. data/md/thread_pool.md +0 -27
  19. data/spec/concurrent/agent_spec.rb +27 -8
  20. data/spec/concurrent/cached_thread_pool_spec.rb +1 -14
  21. data/spec/concurrent/defer_spec.rb +21 -17
  22. data/spec/concurrent/event_machine_defer_proxy_spec.rb +149 -159
  23. data/spec/concurrent/fixed_thread_pool_spec.rb +3 -2
  24. data/spec/concurrent/future_spec.rb +10 -3
  25. data/spec/concurrent/goroutine_spec.rb +0 -15
  26. data/spec/concurrent/obligation_shared.rb +2 -16
  27. data/spec/concurrent/promise_spec.rb +13 -15
  28. data/spec/concurrent/thread_pool_shared.rb +5 -5
  29. data/spec/concurrent/utilities_spec.rb +1 -30
  30. data/spec/spec_helper.rb +0 -25
  31. metadata +7 -28
  32. data/lib/concurrent/executor.rb +0 -95
  33. data/lib/concurrent/functions.rb +0 -120
  34. data/lib/concurrent/null_thread_pool.rb +0 -22
  35. data/lib/concurrent/reactor.rb +0 -161
  36. data/lib/concurrent/reactor/drb_async_demux.rb +0 -74
  37. data/lib/concurrent/reactor/tcp_sync_demux.rb +0 -98
  38. data/md/executor.md +0 -176
  39. data/spec/concurrent/executor_spec.rb +0 -200
  40. data/spec/concurrent/functions_spec.rb +0 -217
  41. data/spec/concurrent/global_thread_pool_spec.rb +0 -38
  42. data/spec/concurrent/null_thread_pool_spec.rb +0 -54
  43. data/spec/concurrent/reactor/drb_async_demux_spec.rb +0 -12
  44. data/spec/concurrent/reactor/tcp_sync_demux_spec.rb +0 -12
  45. data/spec/concurrent/reactor_spec.rb +0 -351
@@ -10,7 +10,6 @@ module Concurrent
10
10
  it_should_behave_like 'Thread Pool'
11
11
 
12
12
  context '#initialize' do
13
-
14
13
  it 'aliases Concurrent#new_cached_thread_pool' do
15
14
  pool = Concurrent.new_cached_thread_pool
16
15
  pool.should be_a(CachedThreadPool)
@@ -21,7 +20,7 @@ module Concurrent
21
20
  context '#kill' do
22
21
 
23
22
  it 'kills all threads' do
24
- Thread.should_receive(:kill).at_least(5).times
23
+ Thread.should_receive(:kill).exactly(5).times
25
24
  pool = CachedThreadPool.new
26
25
  5.times{ sleep(0.1); pool << proc{ sleep(1) } }
27
26
  sleep(1)
@@ -109,17 +108,5 @@ module Concurrent
109
108
  subject.instance_variable_get(:@collector).status.should be_false
110
109
  end
111
110
  end
112
-
113
- context '#status' do
114
-
115
- it 'returns an empty collection when the pool is empty' do
116
- subject.status.should be_empty
117
- end
118
-
119
- it 'returns one status object for each thread in the pool' do
120
- 3.times{ sleep(0.1); subject << proc{ sleep(0.5) } }
121
- subject.status.length.should eq 3
122
- end
123
- end
124
111
  end
125
112
  end
@@ -4,12 +4,12 @@ module Concurrent
4
4
 
5
5
  describe Defer do
6
6
 
7
- before(:each) do
8
- Defer.thread_pool = FixedThreadPool.new(1)
9
- end
10
-
11
7
  context '#initialize' do
12
8
 
9
+ before(:each) do
10
+ $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
11
+ end
12
+
13
13
  it 'raises an exception if no block or operation given' do
14
14
  lambda {
15
15
  Defer.new
@@ -19,19 +19,23 @@ module Concurrent
19
19
  it 'raises an exception if both a block and an operation given' do
20
20
  lambda {
21
21
  operation = proc{ nil }
22
- Defer.new(op: operation){ nil }
22
+ Defer.new(operation, nil, nil){ nil }
23
23
  }.should raise_error(ArgumentError)
24
24
  end
25
25
 
26
26
  it 'starts the thread if an operation is given' do
27
- Defer.thread_pool.should_receive(:post).once.with(any_args())
27
+ $GLOBAL_THREAD_POOL.should_receive(:post).once.with(any_args())
28
28
  operation = proc{ nil }
29
- Defer.new(op: operation)
29
+ Defer.new(operation, nil, nil)
30
30
  end
31
31
 
32
32
  it 'does not start the thread if neither a callback or errorback is given' do
33
- Defer.thread_pool.should_not_receive(:post)
34
- Defer.new{ nil }
33
+ $GLOBAL_THREAD_POOL.should_not_receive(:post)
34
+ Defer.new(nil, nil, nil){ nil }
35
+ end
36
+
37
+ it 'aliases Kernel#defer' do
38
+ defer{ nil }.should be_a(Defer)
35
39
  end
36
40
  end
37
41
 
@@ -52,14 +56,14 @@ module Concurrent
52
56
  it 'raises an exception if an operation was provided at construction' do
53
57
  lambda {
54
58
  operation = proc{ nil }
55
- Defer.new(op: operation).then{|result| nil }
59
+ Defer.new(operation, nil, nil).then{|result| nil }
56
60
  }.should raise_error(IllegalMethodCallError)
57
61
  end
58
62
 
59
63
  it 'raises an exception if a callback was provided at construction' do
60
64
  lambda {
61
65
  callback = proc{|result|nil }
62
- Defer.new(callback: callback){ nil }.then{|result| nil }
66
+ Defer.new(nil, callback, nil){ nil }.then{|result| nil }
63
67
  }.should raise_error(IllegalMethodCallError)
64
68
  end
65
69
 
@@ -86,14 +90,14 @@ module Concurrent
86
90
  it 'raises an exception if an operation was provided at construction' do
87
91
  lambda {
88
92
  operation = proc{ nil }
89
- Defer.new(op: operation).rescue{|ex| nil }
93
+ Defer.new(operation, nil, nil).rescue{|ex| nil }
90
94
  }.should raise_error(IllegalMethodCallError)
91
95
  end
92
96
 
93
97
  it 'raises an exception if an errorback was provided at construction' do
94
98
  lambda {
95
99
  errorback = proc{|ex| nil }
96
- Defer.new(errorback: errorback){ nil }.rescue{|ex| nil }
100
+ Defer.new(nil, nil, errorback){ nil }.rescue{|ex| nil }
97
101
  }.should raise_error(IllegalMethodCallError)
98
102
  end
99
103
 
@@ -119,14 +123,14 @@ module Concurrent
119
123
 
120
124
  it 'starts the thread if not started' do
121
125
  deferred = Defer.new{ nil }
122
- Defer.thread_pool.should_receive(:post).once.with(any_args())
126
+ $GLOBAL_THREAD_POOL.should_receive(:post).once.with(any_args())
123
127
  deferred.go
124
128
  end
125
129
 
126
130
  it 'does nothing if called more than once' do
127
131
  deferred = Defer.new{ nil }
128
132
  deferred.go
129
- Defer.thread_pool.should_not_receive(:post)
133
+ $GLOBAL_THREAD_POOL.should_not_receive(:post)
130
134
  deferred.go
131
135
  end
132
136
 
@@ -134,8 +138,8 @@ module Concurrent
134
138
  operation = proc{ nil }
135
139
  callback = proc{|result| nil }
136
140
  errorback = proc{|ex| nil }
137
- deferred = Defer.new(op: operation, callback: callback, errorback: errorback)
138
- Defer.thread_pool.should_not_receive(:post)
141
+ deferred = Defer.new(operation, callback, errorback)
142
+ $GLOBAL_THREAD_POOL.should_not_receive(:post)
139
143
  deferred.go
140
144
  end
141
145
  end
@@ -2,251 +2,241 @@ require 'spec_helper'
2
2
 
3
3
  require 'concurrent/agent'
4
4
  require 'concurrent/future'
5
- require 'concurrent/goroutine'
6
5
  require 'concurrent/promise'
7
6
 
8
- if mri?
7
+ module Concurrent
9
8
 
10
- module Concurrent
9
+ describe EventMachineDeferProxy do
11
10
 
12
- describe EventMachineDeferProxy do
11
+ subject { EventMachineDeferProxy.new }
13
12
 
14
- subject { EventMachineDeferProxy.new }
13
+ context '#post' do
15
14
 
16
- after(:all) do
17
- $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
15
+ it 'proxies a call without arguments' do
16
+ @expected = false
17
+ EventMachine.run do
18
+ subject.post{ @expected = true }
19
+ sleep(0.1)
20
+ EventMachine.stop
21
+ end
22
+ @expected.should eq true
23
+ end
24
+
25
+ it 'proxies a call with arguments' do
26
+ @expected = []
27
+ EventMachine.run do
28
+ subject.post(1,2,3){|*args| @expected = args }
29
+ sleep(0.1)
30
+ EventMachine.stop
31
+ end
32
+ @expected.should eq [1,2,3]
18
33
  end
19
34
 
20
- context '#post' do
35
+ it 'aliases #<<' do
36
+ @expected = false
37
+ EventMachine.run do
38
+ subject << proc{ @expected = true }
39
+ sleep(0.1)
40
+ EventMachine.stop
41
+ end
42
+ @expected.should eq true
43
+ end
44
+ end
45
+
46
+ context 'operation' do
47
+
48
+ context 'goroutine' do
49
+
50
+ it 'passes all arguments to the block' do
51
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
21
52
 
22
- it 'proxies a call without arguments' do
23
- @expected = false
24
53
  EventMachine.run do
25
- subject.post{ @expected = true }
54
+
55
+ @expected = nil
56
+ go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
26
57
  sleep(0.1)
58
+ @expected.should eq [3, 2, 1]
59
+
27
60
  EventMachine.stop
28
61
  end
29
- @expected.should eq true
30
62
  end
63
+ end
64
+
65
+ context Agent do
66
+
67
+ subject { Agent.new(0) }
68
+
69
+ it 'supports fulfillment' do
70
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
31
71
 
32
- it 'proxies a call with arguments' do
33
- @expected = []
34
72
  EventMachine.run do
35
- subject.post(1,2,3){|*args| @expected = args }
73
+
74
+ @expected = []
75
+ subject.post{ @expected << 1 }
76
+ subject.post{ @expected << 2 }
77
+ subject.post{ @expected << 3 }
36
78
  sleep(0.1)
79
+ @expected.should eq [1,2,3]
80
+
37
81
  EventMachine.stop
38
82
  end
39
- @expected.should eq [1,2,3]
40
83
  end
41
84
 
42
- it 'aliases #<<' do
43
- @expected = false
85
+ it 'supports validation' do
86
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
87
+
44
88
  EventMachine.run do
45
- subject << proc{ @expected = true }
89
+
90
+ @expected = nil
91
+ subject.validate{ @expected = 10; true }
92
+ subject.post{ nil }
46
93
  sleep(0.1)
94
+ @expected.should eq 10
95
+
47
96
  EventMachine.stop
48
97
  end
49
- @expected.should eq true
50
98
  end
51
- end
52
99
 
53
- context 'operation' do
100
+ it 'supports rejection' do
101
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
54
102
 
55
- context 'goroutine' do
103
+ EventMachine.run do
56
104
 
57
- it 'passes all arguments to the block' do
58
- $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
105
+ @expected = nil
106
+ subject.
107
+ on_error(StandardError){|ex| @expected = 1 }.
108
+ on_error(StandardError){|ex| @expected = 2 }.
109
+ on_error(StandardError){|ex| @expected = 3 }
110
+ subject.post{ raise StandardError }
111
+ sleep(0.1)
112
+ @expected.should eq 1
59
113
 
60
- EventMachine.run do
114
+ EventMachine.stop
115
+ end
116
+ end
117
+ end
61
118
 
62
- @expected = nil
63
- go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
64
- sleep(0.1)
65
- @expected.should eq [3, 2, 1]
119
+ context Future do
66
120
 
67
- EventMachine.stop
121
+ it 'supports fulfillment' do
122
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
123
+
124
+ EventMachine.run do
125
+
126
+ @a = @b = @c = nil
127
+ f = Future.new(1, 2, 3) do |a, b, c|
128
+ @a, @b, @c = a, b, c
68
129
  end
130
+ sleep(0.1)
131
+ [@a, @b, @c].should eq [1, 2, 3]
132
+
133
+ sleep(0.1)
134
+ EventMachine.stop
69
135
  end
70
136
  end
137
+ end
71
138
 
72
- context Agent do
73
-
74
- subject { Agent.new(0) }
139
+ context Promise do
75
140
 
76
- before(:each) do
77
- Agent.thread_pool = EventMachineDeferProxy.new
78
- end
141
+ context 'fulfillment' do
79
142
 
80
- it 'supports fulfillment' do
143
+ it 'passes all arguments to the first promise in the chain' do
144
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
81
145
 
82
146
  EventMachine.run do
83
147
 
84
- @expected = []
85
- subject.post{ @expected << 1 }
86
- subject.post{ @expected << 2 }
87
- subject.post{ @expected << 3 }
148
+ @a = @b = @c = nil
149
+ p = Promise.new(1, 2, 3) do |a, b, c|
150
+ @a, @b, @c = a, b, c
151
+ end
88
152
  sleep(0.1)
89
- @expected.should eq [1,2,3]
153
+ [@a, @b, @c].should eq [1, 2, 3]
90
154
 
155
+ sleep(0.1)
91
156
  EventMachine.stop
92
157
  end
93
158
  end
94
159
 
95
- it 'supports validation' do
160
+ it 'passes the result of each block to all its children' do
161
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
96
162
 
97
163
  EventMachine.run do
98
-
99
164
  @expected = nil
100
- subject.validate{ @expected = 10; true }
101
- subject.post{ nil }
165
+ Promise.new(10){|a| a * 2 }.then{|result| @expected = result}
102
166
  sleep(0.1)
103
- @expected.should eq 10
167
+ @expected.should eq 20
104
168
 
169
+ sleep(0.1)
105
170
  EventMachine.stop
106
171
  end
107
172
  end
108
173
 
109
- it 'supports rejection' do
174
+ it 'sets the promise value to the result if its block' do
175
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
110
176
 
111
177
  EventMachine.run do
112
178
 
113
- @expected = nil
114
- subject.
115
- on_error(StandardError){|ex| @expected = 1 }.
116
- on_error(StandardError){|ex| @expected = 2 }.
117
- on_error(StandardError){|ex| @expected = 3 }
118
- subject.post{ raise StandardError }
179
+ p = Promise.new(10){|a| a * 2 }.then{|result| result * 2}
119
180
  sleep(0.1)
120
- @expected.should eq 1
181
+ p.value.should eq 40
121
182
 
183
+ sleep(0.1)
122
184
  EventMachine.stop
123
185
  end
124
186
  end
125
187
  end
126
188
 
127
- context Future do
128
-
129
- before(:each) do
130
- Future.thread_pool = EventMachineDeferProxy.new
131
- end
189
+ context 'rejection' do
132
190
 
133
- it 'supports fulfillment' do
191
+ it 'sets the promise reason and error on exception' do
192
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
134
193
 
135
194
  EventMachine.run do
136
195
 
137
- @a = @b = @c = nil
138
- f = Future.new(1, 2, 3) do |a, b, c|
139
- @a, @b, @c = a, b, c
140
- end
196
+ p = Promise.new{ raise StandardError.new('Boom!') }
141
197
  sleep(0.1)
142
- [@a, @b, @c].should eq [1, 2, 3]
198
+ p.reason.should be_a(Exception)
199
+ p.reason.should.to_s =~ /Boom!/
200
+ p.should be_rejected
143
201
 
144
202
  sleep(0.1)
145
203
  EventMachine.stop
146
204
  end
147
205
  end
148
- end
149
-
150
- context Promise do
151
-
152
- before(:each) do
153
- Promise.thread_pool = EventMachineDeferProxy.new
154
- end
155
-
156
- context 'fulfillment' do
157
206
 
158
- it 'passes all arguments to the first promise in the chain' do
159
-
160
- EventMachine.run do
161
-
162
- @a = @b = @c = nil
163
- p = Promise.new(1, 2, 3) do |a, b, c|
164
- @a, @b, @c = a, b, c
165
- end
166
- sleep(0.1)
167
- [@a, @b, @c].should eq [1, 2, 3]
168
-
169
- sleep(0.1)
170
- EventMachine.stop
171
- end
172
- end
173
-
174
- it 'passes the result of each block to all its children' do
175
-
176
- EventMachine.run do
177
- @expected = nil
178
- Promise.new(10){|a| a * 2 }.then{|result| @expected = result}
179
- sleep(0.1)
180
- @expected.should eq 20
181
-
182
- sleep(0.1)
183
- EventMachine.stop
184
- end
185
- end
186
-
187
- it 'sets the promise value to the result if its block' do
207
+ it 'calls the first exception block with a matching class' do
208
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
188
209
 
189
- EventMachine.run do
210
+ EventMachine.run do
190
211
 
191
- p = Promise.new(10){|a| a * 2 }.then{|result| result * 2}
192
- sleep(0.1)
193
- p.value.should eq 40
212
+ @expected = nil
213
+ Promise.new{ raise StandardError }.
214
+ on_error(StandardError){|ex| @expected = 1 }.
215
+ on_error(StandardError){|ex| @expected = 2 }.
216
+ on_error(StandardError){|ex| @expected = 3 }
217
+ sleep(0.1)
218
+ @expected.should eq 1
194
219
 
195
- sleep(0.1)
196
- EventMachine.stop
197
- end
220
+ sleep(0.1)
221
+ EventMachine.stop
198
222
  end
199
223
  end
200
224
 
201
- context 'rejection' do
202
-
203
- it 'sets the promise reason and error on exception' do
204
-
205
- EventMachine.run do
206
-
207
- p = Promise.new{ raise StandardError.new('Boom!') }
208
- sleep(0.1)
209
- p.reason.should be_a(Exception)
210
- p.reason.should.to_s =~ /Boom!/
211
- p.should be_rejected
212
-
213
- sleep(0.1)
214
- EventMachine.stop
215
- end
216
- end
217
-
218
- it 'calls the first exception block with a matching class' do
219
-
220
- EventMachine.run do
221
-
222
- @expected = nil
223
- Promise.new{ raise StandardError }.
224
- on_error(StandardError){|ex| @expected = 1 }.
225
- on_error(StandardError){|ex| @expected = 2 }.
226
- on_error(StandardError){|ex| @expected = 3 }
227
- sleep(0.1)
228
- @expected.should eq 1
229
-
230
- sleep(0.1)
231
- EventMachine.stop
232
- end
233
- end
234
-
235
- it 'passes the exception object to the matched block' do
225
+ it 'passes the exception object to the matched block' do
226
+ $GLOBAL_THREAD_POOL = EventMachineDeferProxy.new
236
227
 
237
- EventMachine.run do
228
+ EventMachine.run do
238
229
 
239
- @expected = nil
240
- Promise.new{ raise StandardError }.
241
- on_error(ArgumentError){|ex| @expected = ex }.
242
- on_error(LoadError){|ex| @expected = ex }.
243
- on_error(Exception){|ex| @expected = ex }
244
- sleep(0.1)
245
- @expected.should be_a(StandardError)
230
+ @expected = nil
231
+ Promise.new{ raise StandardError }.
232
+ on_error(ArgumentError){|ex| @expected = ex }.
233
+ on_error(LoadError){|ex| @expected = ex }.
234
+ on_error(Exception){|ex| @expected = ex }
235
+ sleep(0.1)
236
+ @expected.should be_a(StandardError)
246
237
 
247
- sleep(0.1)
248
- EventMachine.stop
249
- end
238
+ sleep(0.1)
239
+ EventMachine.stop
250
240
  end
251
241
  end
252
242
  end