concurrent-ruby 0.2.0 → 0.2.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 (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.