concurrent-ruby 0.1.0 → 0.1.1.pre.1

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