concurrent-ruby 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/LICENSE +21 -21
  2. data/README.md +275 -275
  3. data/lib/concurrent.rb +28 -28
  4. data/lib/concurrent/agent.rb +114 -114
  5. data/lib/concurrent/cached_thread_pool.rb +131 -129
  6. data/lib/concurrent/defer.rb +65 -65
  7. data/lib/concurrent/event.rb +60 -60
  8. data/lib/concurrent/event_machine_defer_proxy.rb +23 -23
  9. data/lib/concurrent/executor.rb +96 -95
  10. data/lib/concurrent/fixed_thread_pool.rb +99 -95
  11. data/lib/concurrent/functions.rb +120 -120
  12. data/lib/concurrent/future.rb +42 -42
  13. data/lib/concurrent/global_thread_pool.rb +16 -16
  14. data/lib/concurrent/goroutine.rb +29 -29
  15. data/lib/concurrent/null_thread_pool.rb +22 -22
  16. data/lib/concurrent/obligation.rb +67 -67
  17. data/lib/concurrent/promise.rb +174 -174
  18. data/lib/concurrent/reactor.rb +166 -166
  19. data/lib/concurrent/reactor/drb_async_demux.rb +83 -83
  20. data/lib/concurrent/reactor/tcp_sync_demux.rb +131 -131
  21. data/lib/concurrent/supervisor.rb +105 -100
  22. data/lib/concurrent/thread_pool.rb +76 -76
  23. data/lib/concurrent/utilities.rb +32 -32
  24. data/lib/concurrent/version.rb +3 -3
  25. data/lib/concurrent_ruby.rb +1 -1
  26. data/md/agent.md +123 -123
  27. data/md/defer.md +174 -174
  28. data/md/event.md +32 -32
  29. data/md/executor.md +187 -187
  30. data/md/future.md +83 -83
  31. data/md/goroutine.md +52 -52
  32. data/md/obligation.md +32 -32
  33. data/md/promise.md +227 -227
  34. data/md/thread_pool.md +224 -224
  35. data/spec/concurrent/agent_spec.rb +386 -386
  36. data/spec/concurrent/cached_thread_pool_spec.rb +125 -125
  37. data/spec/concurrent/defer_spec.rb +195 -195
  38. data/spec/concurrent/event_machine_defer_proxy_spec.rb +256 -256
  39. data/spec/concurrent/event_spec.rb +134 -134
  40. data/spec/concurrent/executor_spec.rb +200 -200
  41. data/spec/concurrent/fixed_thread_pool_spec.rb +83 -83
  42. data/spec/concurrent/functions_spec.rb +217 -217
  43. data/spec/concurrent/future_spec.rb +108 -108
  44. data/spec/concurrent/global_thread_pool_spec.rb +38 -38
  45. data/spec/concurrent/goroutine_spec.rb +67 -67
  46. data/spec/concurrent/null_thread_pool_spec.rb +57 -54
  47. data/spec/concurrent/obligation_shared.rb +132 -132
  48. data/spec/concurrent/promise_spec.rb +312 -312
  49. data/spec/concurrent/reactor/drb_async_demux_spec.rb +196 -196
  50. data/spec/concurrent/reactor/tcp_sync_demux_spec.rb +410 -410
  51. data/spec/concurrent/reactor_spec.rb +364 -364
  52. data/spec/concurrent/supervisor_spec.rb +269 -258
  53. data/spec/concurrent/thread_pool_shared.rb +204 -204
  54. data/spec/concurrent/utilities_spec.rb +74 -74
  55. data/spec/spec_helper.rb +32 -32
  56. metadata +20 -16
  57. checksums.yaml +0 -7
data/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- Copyright (c) Jerry D'Antonio -- released under the MIT license.
2
-
3
- http://www.opensource.org/licenses/mit-license.php
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ Copyright (c) Jerry D'Antonio -- released under the MIT license.
2
+
3
+ http://www.opensource.org/licenses/mit-license.php
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,275 +1,275 @@
1
- # Concurrent Ruby [![Build Status](https://secure.travis-ci.org/jdantonio/concurrent-ruby.png)](https://travis-ci.org/jdantonio/concurrent-ruby?branch=master) [![Dependency Status](https://gemnasium.com/jdantonio/concurrent-ruby.png)](https://gemnasium.com/jdantonio/concurrent-ruby)
2
-
3
- Erlang, Clojure, and Go inspired concurrent programming tools for Ruby.
4
-
5
- ## Introduction
6
-
7
- The old-school "lock and synchronize" approach to concurrency is dead. The future of concurrency
8
- is asynchronous. Send out a bunch of independent [actors](http://en.wikipedia.org/wiki/Actor_model)
9
- to do your bidding and process the results when you are ready. Although the idea of the concurrent
10
- actor originated in the early 1970's it has only recently started catching on. Although there is
11
- no one "true" actor implementation (what *exactly* is "object oriented," what *exactly* is
12
- "concurrent programming"), many modern programming languages implement variations on the actor
13
- theme. This library implements a few of the most interesting and useful of those variations.
14
-
15
- Remember, *there is no silver bullet in concurrent programming.* Concurrency is hard. Very hard.
16
- These tools will help ease the burden, but at the end of the day it is essential that you
17
- *know what you are doing.*
18
-
19
- The project is hosted on the following sites:
20
-
21
- * [RubyGems project page](https://rubygems.org/gems/concurrent-ruby)
22
- * [Source code on GitHub](https://github.com/jdantonio/concurrent-ruby)
23
- * [YARD documentation on RubyDoc.info](http://rubydoc.info/github/jdantonio/concurrent-ruby/frames)
24
- * [Continuous integration on Travis-CI](https://travis-ci.org/jdantonio/concurrent-ruby)
25
- * [Dependency tracking on Gemnasium](https://gemnasium.com/jdantonio/concurrent-ruby)
26
- * [Follow me on Twitter](https://twitter.com/jerrydantonio)
27
-
28
- ### Goals
29
-
30
- My history with high-performance, highly-concurrent programming goes back to my days with C/C++.
31
- I have the same scars as everyone else doing that kind of work with those languages.
32
- I'm fascinated by modern concurrency patterns like [Actors](http://en.wikipedia.org/wiki/Actor_model),
33
- [Agents](http://doc.akka.io/docs/akka/snapshot/java/agents.html), and
34
- [Promises](http://promises-aplus.github.io/promises-spec/). I'm equally fascinated by languages
35
- with strong concurrency support like [Erlang](http://www.erlang.org/doc/getting_started/conc_prog.html),
36
- [Go](http://golang.org/doc/articles/concurrency_patterns.html), and
37
- [Clojure](http://clojure.org/concurrent_programming). My goal is to implement those patterns in Ruby.
38
- Specifically:
39
-
40
- * Stay true to the spirit of the languages providing inspiration
41
- * But implement in a way that makes sense for Ruby
42
- * Keep the semantics as idiomatic Ruby as possible
43
- * Support features that make sense in Ruby
44
- * Exclude features that don't make sense in Ruby
45
- * Keep everything small
46
- * Be as fast as reasonably possible
47
-
48
- ## Features (and Documentation)
49
-
50
- Several features from Erlang, Go, Clojure, Java, and JavaScript have been implemented thus far:
51
-
52
- * Clojure inspired [Agent](https://github.com/jdantonio/concurrent-ruby/blob/master/md/agent.md)
53
- * EventMachine inspired [Defer](https://github.com/jdantonio/concurrent-ruby/blob/master/md/defer.md)
54
- * Clojure inspired [Future](https://github.com/jdantonio/concurrent-ruby/blob/master/md/future.md)
55
- * Go inspired [Goroutine](https://github.com/jdantonio/concurrent-ruby/blob/master/md/goroutine.md)
56
- * JavaScript inspired [Promise](https://github.com/jdantonio/concurrent-ruby/blob/master/md/promise.md)
57
- * Java inspired [Thread Pools](https://github.com/jdantonio/concurrent-ruby/blob/master/md/thread_pool.md)
58
- * Scheduled task execution with the [Executor](https://github.com/jdantonio/concurrent-ruby/blob/master/md/executor.md) service
59
-
60
- ### Is it any good?
61
-
62
- [Yes](http://news.ycombinator.com/item?id=3067434)
63
-
64
- ### Supported Ruby versions
65
-
66
- MRI 1.9.2, 1.9.3, and 2.0. This library is pure Ruby and has minimal gem dependencies. It should be
67
- fully compatible with any Ruby interpreter that is 1.9.x compliant. I simply don't know enough
68
- about JRuby, Rubinius, or the others to fully support them. I can promise good karma and
69
- attribution on this page to anyone wishing to take responsibility for verifying compaitibility
70
- with any Ruby other than MRI.
71
-
72
- ### Install
73
-
74
- ```shell
75
- gem install concurrent-ruby
76
- ```
77
-
78
- or add the following line to Gemfile:
79
-
80
- ```ruby
81
- gem 'concurrent-ruby'
82
- ```
83
-
84
- and run `bundle install` from your shell.
85
-
86
- Once you've installed the gem you must `require` it in your project:
87
-
88
- ```ruby
89
- require 'concurrent'
90
- ```
91
-
92
- ### Kernel Methods
93
-
94
- Many Ruby developers consider it bad form to add function to the global (Kernel) namespace.
95
- I don't necessarily agree. If the function acts like a low-level feature of the language
96
- I think it is OK to add the method to the `Kernel` module. To support my personal programming
97
- style I have chosen to implement `Kernel` methods to instance many of the objects in this
98
- library. Out of respect for the larger Ruby community I have made these methods optional.
99
- They are not imported with the normal `require 'concurrent'` directive. To import these
100
- functions you must import the `concurrent/functions` library.
101
-
102
- ```ruby
103
- require 'concurrent'
104
- score = agent(10) #=> NoMethodError: undefined method `agent' for main:Object
105
-
106
- require 'concurrent/functions'
107
- score = agent(10) #=> #<Concurrent::Agent:0x35b2b28 ...
108
- score.value #=> 10
109
- ```
110
-
111
- ### Examples
112
-
113
- For complete examples, see the specific documentation linked above. Below are a few examples to whet your appetite.
114
-
115
- #### Goroutine (Go)
116
-
117
- ```ruby
118
- require 'concurrent'
119
-
120
- @expected = nil
121
- go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
122
- sleep(0.1)
123
- @expected #=> [3, 2, 1]
124
- ```
125
-
126
- #### Agent (Clojure)
127
-
128
- ```ruby
129
- require 'concurrent'
130
- require 'concurrent/functions'
131
-
132
- score = agent(10)
133
- score.value #=> 10
134
-
135
- score << proc{|current| current + 100 }
136
- sleep(0.1)
137
- score.value #=> 110
138
-
139
- score << proc{|current| current * 2 }
140
- sleep(0.1)
141
- deref score #=> 220
142
-
143
- score << proc{|current| current - 50 }
144
- sleep(0.1)
145
- score.value #=> 170
146
- ```
147
-
148
- #### Defer (EventMachine)
149
-
150
- ```ruby
151
- require 'concurrent'
152
- require 'concurrent/functions'
153
-
154
- Concurrent::Defer.new{ "Jerry D'Antonio" }.
155
- then{|result| puts "Hello, #{result}!" }.
156
- rescue{|ex| puts ex.message }.
157
- go
158
-
159
- #=> Hello, Jerry D'Antonio!
160
-
161
- operation = proc{ raise StandardError.new('Boom!') }
162
- callback = proc{|result| puts result }
163
- errorback = proc{|ex| puts ex.message }
164
- defer(operation, callback, errorback)
165
- sleep(0.1)
166
-
167
- #=> "Boom!"
168
- ```
169
-
170
- #### Future (Clojure)
171
-
172
- ```ruby
173
- require 'concurrent'
174
- require 'concurrent/functions'
175
-
176
- count = future{ sleep(1); 10 }
177
- count.state #=> :pending
178
- # do stuff...
179
- count.value #=> 10 (after blocking)
180
- deref count #=> 10
181
- ```
182
-
183
- #### Promise (JavaScript)
184
-
185
- ```ruby
186
- require 'concurrent'
187
- require 'concurrent/functions'
188
-
189
- p = promise("Jerry", "D'Antonio"){|a, b| "#{a} #{b}" }.
190
- then{|result| "Hello #{result}." }.
191
- rescue(StandardError){|ex| puts "Boom!" }.
192
- then{|result| "#{result} Would you like to play a game?"}
193
- sleep(1)
194
- p.value #=> "Hello Jerry D'Antonio. Would you like to play a game?"
195
- ```
196
-
197
- #### Thread Pools
198
-
199
- ```ruby
200
- require 'concurrent'
201
-
202
- pool = Concurrent::FixedThreadPool.new(10)
203
- @expected = 0
204
- pool.post{ sleep(0.5); @expected += 100 }
205
- pool.post{ sleep(0.5); @expected += 100 }
206
- pool.post{ sleep(0.5); @expected += 100 }
207
- @expected #=> nil
208
- sleep(1)
209
- @expected #=> 300
210
-
211
- pool = Concurrent::CachedThreadPool.new
212
- @expected = 0
213
- pool << proc{ sleep(0.5); @expected += 10 }
214
- pool << proc{ sleep(0.5); @expected += 10 }
215
- pool << proc{ sleep(0.5); @expected += 10 }
216
- @expected #=> 0
217
- sleep(1)
218
- @expected #=> 30
219
- ```
220
-
221
- #### Executor
222
-
223
- ```ruby
224
- require 'concurrent'
225
-
226
- ec = Concurrent::Executor.run('Foo'){ puts 'Boom!' }
227
-
228
- ec.name #=> "Foo"
229
- ec.execution_interval #=> 60 == Concurrent::Executor::EXECUTION_INTERVAL
230
- ec.timeout_interval #=> 30 == Concurrent::Executor::TIMEOUT_INTERVAL
231
- ec.status #=> "sleep"
232
-
233
- # wait 60 seconds...
234
- #=> 'Boom!'
235
- #=> ' INFO (2013-08-02 23:20:15) Foo: execution completed successfully'
236
-
237
- ec.kill #=> true
238
- ```
239
-
240
- ## Contributing
241
-
242
- 1. Fork it
243
- 2. Create your feature branch (`git checkout -b my-new-feature`)
244
- 3. Commit your changes (`git commit -am 'Add some feature'`)
245
- 4. Push to the branch (`git push origin my-new-feature`)
246
- 5. Create new Pull Request
247
-
248
- ## Copyright
249
-
250
- *Concurrent Ruby* is Copyright &copy; 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
251
- It is free software and may be redistributed under the terms specified in the LICENSE file.
252
-
253
- ## License
254
-
255
- Released under the MIT license.
256
-
257
- http://www.opensource.org/licenses/mit-license.php
258
-
259
- > Permission is hereby granted, free of charge, to any person obtaining a copy
260
- > of this software and associated documentation files (the "Software"), to deal
261
- > in the Software without restriction, including without limitation the rights
262
- > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
263
- > copies of the Software, and to permit persons to whom the Software is
264
- > furnished to do so, subject to the following conditions:
265
- >
266
- > The above copyright notice and this permission notice shall be included in
267
- > all copies or substantial portions of the Software.
268
- >
269
- > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
270
- > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
271
- > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
272
- > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
273
- > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
274
- > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
275
- > THE SOFTWARE.
1
+ # Concurrent Ruby [![Build Status](https://secure.travis-ci.org/jdantonio/concurrent-ruby.png)](https://travis-ci.org/jdantonio/concurrent-ruby?branch=master) [![Dependency Status](https://gemnasium.com/jdantonio/concurrent-ruby.png)](https://gemnasium.com/jdantonio/concurrent-ruby)
2
+
3
+ Erlang, Clojure, and Go inspired concurrent programming tools for Ruby.
4
+
5
+ ## Introduction
6
+
7
+ The old-school "lock and synchronize" approach to concurrency is dead. The future of concurrency
8
+ is asynchronous. Send out a bunch of independent [actors](http://en.wikipedia.org/wiki/Actor_model)
9
+ to do your bidding and process the results when you are ready. Although the idea of the concurrent
10
+ actor originated in the early 1970's it has only recently started catching on. Although there is
11
+ no one "true" actor implementation (what *exactly* is "object oriented," what *exactly* is
12
+ "concurrent programming"), many modern programming languages implement variations on the actor
13
+ theme. This library implements a few of the most interesting and useful of those variations.
14
+
15
+ Remember, *there is no silver bullet in concurrent programming.* Concurrency is hard. Very hard.
16
+ These tools will help ease the burden, but at the end of the day it is essential that you
17
+ *know what you are doing.*
18
+
19
+ The project is hosted on the following sites:
20
+
21
+ * [RubyGems project page](https://rubygems.org/gems/concurrent-ruby)
22
+ * [Source code on GitHub](https://github.com/jdantonio/concurrent-ruby)
23
+ * [YARD documentation on RubyDoc.info](http://rubydoc.info/github/jdantonio/concurrent-ruby/frames)
24
+ * [Continuous integration on Travis-CI](https://travis-ci.org/jdantonio/concurrent-ruby)
25
+ * [Dependency tracking on Gemnasium](https://gemnasium.com/jdantonio/concurrent-ruby)
26
+ * [Follow me on Twitter](https://twitter.com/jerrydantonio)
27
+
28
+ ### Goals
29
+
30
+ My history with high-performance, highly-concurrent programming goes back to my days with C/C++.
31
+ I have the same scars as everyone else doing that kind of work with those languages.
32
+ I'm fascinated by modern concurrency patterns like [Actors](http://en.wikipedia.org/wiki/Actor_model),
33
+ [Agents](http://doc.akka.io/docs/akka/snapshot/java/agents.html), and
34
+ [Promises](http://promises-aplus.github.io/promises-spec/). I'm equally fascinated by languages
35
+ with strong concurrency support like [Erlang](http://www.erlang.org/doc/getting_started/conc_prog.html),
36
+ [Go](http://golang.org/doc/articles/concurrency_patterns.html), and
37
+ [Clojure](http://clojure.org/concurrent_programming). My goal is to implement those patterns in Ruby.
38
+ Specifically:
39
+
40
+ * Stay true to the spirit of the languages providing inspiration
41
+ * But implement in a way that makes sense for Ruby
42
+ * Keep the semantics as idiomatic Ruby as possible
43
+ * Support features that make sense in Ruby
44
+ * Exclude features that don't make sense in Ruby
45
+ * Keep everything small
46
+ * Be as fast as reasonably possible
47
+
48
+ ## Features (and Documentation)
49
+
50
+ Several features from Erlang, Go, Clojure, Java, and JavaScript have been implemented thus far:
51
+
52
+ * Clojure inspired [Agent](https://github.com/jdantonio/concurrent-ruby/blob/master/md/agent.md)
53
+ * EventMachine inspired [Defer](https://github.com/jdantonio/concurrent-ruby/blob/master/md/defer.md)
54
+ * Clojure inspired [Future](https://github.com/jdantonio/concurrent-ruby/blob/master/md/future.md)
55
+ * Go inspired [Goroutine](https://github.com/jdantonio/concurrent-ruby/blob/master/md/goroutine.md)
56
+ * JavaScript inspired [Promise](https://github.com/jdantonio/concurrent-ruby/blob/master/md/promise.md)
57
+ * Java inspired [Thread Pools](https://github.com/jdantonio/concurrent-ruby/blob/master/md/thread_pool.md)
58
+ * Scheduled task execution with the [Executor](https://github.com/jdantonio/concurrent-ruby/blob/master/md/executor.md) service
59
+
60
+ ### Is it any good?
61
+
62
+ [Yes](http://news.ycombinator.com/item?id=3067434)
63
+
64
+ ### Supported Ruby versions
65
+
66
+ MRI 1.9.2, 1.9.3, and 2.0. This library is pure Ruby and has minimal gem dependencies. It should be
67
+ fully compatible with any Ruby interpreter that is 1.9.x compliant. I simply don't know enough
68
+ about JRuby, Rubinius, or the others to fully support them. I can promise good karma and
69
+ attribution on this page to anyone wishing to take responsibility for verifying compaitibility
70
+ with any Ruby other than MRI.
71
+
72
+ ### Install
73
+
74
+ ```shell
75
+ gem install concurrent-ruby
76
+ ```
77
+
78
+ or add the following line to Gemfile:
79
+
80
+ ```ruby
81
+ gem 'concurrent-ruby'
82
+ ```
83
+
84
+ and run `bundle install` from your shell.
85
+
86
+ Once you've installed the gem you must `require` it in your project:
87
+
88
+ ```ruby
89
+ require 'concurrent'
90
+ ```
91
+
92
+ ### Kernel Methods
93
+
94
+ Many Ruby developers consider it bad form to add function to the global (Kernel) namespace.
95
+ I don't necessarily agree. If the function acts like a low-level feature of the language
96
+ I think it is OK to add the method to the `Kernel` module. To support my personal programming
97
+ style I have chosen to implement `Kernel` methods to instance many of the objects in this
98
+ library. Out of respect for the larger Ruby community I have made these methods optional.
99
+ They are not imported with the normal `require 'concurrent'` directive. To import these
100
+ functions you must import the `concurrent/functions` library.
101
+
102
+ ```ruby
103
+ require 'concurrent'
104
+ score = agent(10) #=> NoMethodError: undefined method `agent' for main:Object
105
+
106
+ require 'concurrent/functions'
107
+ score = agent(10) #=> #<Concurrent::Agent:0x35b2b28 ...
108
+ score.value #=> 10
109
+ ```
110
+
111
+ ### Examples
112
+
113
+ For complete examples, see the specific documentation linked above. Below are a few examples to whet your appetite.
114
+
115
+ #### Goroutine (Go)
116
+
117
+ ```ruby
118
+ require 'concurrent'
119
+
120
+ @expected = nil
121
+ go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
122
+ sleep(0.1)
123
+ @expected #=> [3, 2, 1]
124
+ ```
125
+
126
+ #### Agent (Clojure)
127
+
128
+ ```ruby
129
+ require 'concurrent'
130
+ require 'concurrent/functions'
131
+
132
+ score = agent(10)
133
+ score.value #=> 10
134
+
135
+ score << proc{|current| current + 100 }
136
+ sleep(0.1)
137
+ score.value #=> 110
138
+
139
+ score << proc{|current| current * 2 }
140
+ sleep(0.1)
141
+ deref score #=> 220
142
+
143
+ score << proc{|current| current - 50 }
144
+ sleep(0.1)
145
+ score.value #=> 170
146
+ ```
147
+
148
+ #### Defer (EventMachine)
149
+
150
+ ```ruby
151
+ require 'concurrent'
152
+ require 'concurrent/functions'
153
+
154
+ Concurrent::Defer.new{ "Jerry D'Antonio" }.
155
+ then{|result| puts "Hello, #{result}!" }.
156
+ rescue{|ex| puts ex.message }.
157
+ go
158
+
159
+ #=> Hello, Jerry D'Antonio!
160
+
161
+ operation = proc{ raise StandardError.new('Boom!') }
162
+ callback = proc{|result| puts result }
163
+ errorback = proc{|ex| puts ex.message }
164
+ defer(operation, callback, errorback)
165
+ sleep(0.1)
166
+
167
+ #=> "Boom!"
168
+ ```
169
+
170
+ #### Future (Clojure)
171
+
172
+ ```ruby
173
+ require 'concurrent'
174
+ require 'concurrent/functions'
175
+
176
+ count = future{ sleep(1); 10 }
177
+ count.state #=> :pending
178
+ # do stuff...
179
+ count.value #=> 10 (after blocking)
180
+ deref count #=> 10
181
+ ```
182
+
183
+ #### Promise (JavaScript)
184
+
185
+ ```ruby
186
+ require 'concurrent'
187
+ require 'concurrent/functions'
188
+
189
+ p = promise("Jerry", "D'Antonio"){|a, b| "#{a} #{b}" }.
190
+ then{|result| "Hello #{result}." }.
191
+ rescue(StandardError){|ex| puts "Boom!" }.
192
+ then{|result| "#{result} Would you like to play a game?"}
193
+ sleep(1)
194
+ p.value #=> "Hello Jerry D'Antonio. Would you like to play a game?"
195
+ ```
196
+
197
+ #### Thread Pools
198
+
199
+ ```ruby
200
+ require 'concurrent'
201
+
202
+ pool = Concurrent::FixedThreadPool.new(10)
203
+ @expected = 0
204
+ pool.post{ sleep(0.5); @expected += 100 }
205
+ pool.post{ sleep(0.5); @expected += 100 }
206
+ pool.post{ sleep(0.5); @expected += 100 }
207
+ @expected #=> nil
208
+ sleep(1)
209
+ @expected #=> 300
210
+
211
+ pool = Concurrent::CachedThreadPool.new
212
+ @expected = 0
213
+ pool << proc{ sleep(0.5); @expected += 10 }
214
+ pool << proc{ sleep(0.5); @expected += 10 }
215
+ pool << proc{ sleep(0.5); @expected += 10 }
216
+ @expected #=> 0
217
+ sleep(1)
218
+ @expected #=> 30
219
+ ```
220
+
221
+ #### Executor
222
+
223
+ ```ruby
224
+ require 'concurrent'
225
+
226
+ ec = Concurrent::Executor.run('Foo'){ puts 'Boom!' }
227
+
228
+ ec.name #=> "Foo"
229
+ ec.execution_interval #=> 60 == Concurrent::Executor::EXECUTION_INTERVAL
230
+ ec.timeout_interval #=> 30 == Concurrent::Executor::TIMEOUT_INTERVAL
231
+ ec.status #=> "sleep"
232
+
233
+ # wait 60 seconds...
234
+ #=> 'Boom!'
235
+ #=> ' INFO (2013-08-02 23:20:15) Foo: execution completed successfully'
236
+
237
+ ec.kill #=> true
238
+ ```
239
+
240
+ ## Contributing
241
+
242
+ 1. Fork it
243
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
244
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
245
+ 4. Push to the branch (`git push origin my-new-feature`)
246
+ 5. Create new Pull Request
247
+
248
+ ## Copyright
249
+
250
+ *Concurrent Ruby* is Copyright &copy; 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
251
+ It is free software and may be redistributed under the terms specified in the LICENSE file.
252
+
253
+ ## License
254
+
255
+ Released under the MIT license.
256
+
257
+ http://www.opensource.org/licenses/mit-license.php
258
+
259
+ > Permission is hereby granted, free of charge, to any person obtaining a copy
260
+ > of this software and associated documentation files (the "Software"), to deal
261
+ > in the Software without restriction, including without limitation the rights
262
+ > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
263
+ > copies of the Software, and to permit persons to whom the Software is
264
+ > furnished to do so, subject to the following conditions:
265
+ >
266
+ > The above copyright notice and this permission notice shall be included in
267
+ > all copies or substantial portions of the Software.
268
+ >
269
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
270
+ > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
271
+ > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
272
+ > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
273
+ > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
274
+ > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
275
+ > THE SOFTWARE.