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
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,224 +1,279 @@
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
-
59
- ### Is it any good?
60
-
61
- [Yes](http://news.ycombinator.com/item?id=3067434)
62
-
63
- ### Supported Ruby versions
64
-
65
- MRI 1.9.2, 1.9.3, and 2.0. This library is pure Ruby and has no gem dependencies. It should be
66
- fully compatible with any Ruby interpreter that is 1.9.x compliant. I simply don't know enough
67
- about JRuby, Rubinius, or the others to fully support them. I can promise good karma and
68
- attribution on this page to anyone wishing to take responsibility for verifying compaitibility
69
- with any Ruby other than MRI.
70
-
71
- ### Install
72
-
73
- ```shell
74
- gem install concurrent-ruby
75
- ```
76
-
77
- or add the following line to Gemfile:
78
-
79
- ```ruby
80
- gem 'concurrent-ruby'
81
- ```
82
-
83
- and run `bundle install` from your shell.
84
-
85
- Once you've installed the gem you must `require` it in your project:
86
-
87
- ```ruby
88
- require 'concurrent'
89
- ```
90
-
91
- ### Examples
92
-
93
- For complete examples, see the specific documentation linked above. Below are a few examples to whet your appetite.
94
-
95
- #### Goroutine (Go)
96
-
97
- ```ruby
98
- require 'concurrent'
99
-
100
- @expected = nil
101
- go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
102
- sleep(0.1)
103
- @expected #=> [3, 2, 1]
104
- ```
105
-
106
- #### Agent (Clojure)
107
-
108
- ```ruby
109
- require 'concurrent'
110
-
111
- score = agent(10)
112
- score.value #=> 10
113
-
114
- score << proc{|current| current + 100 }
115
- sleep(0.1)
116
- score.value #=> 110
117
-
118
- score << proc{|current| current * 2 }
119
- sleep(0.1)
120
- deref score #=> 220
121
-
122
- score << proc{|current| current - 50 }
123
- sleep(0.1)
124
- score.value #=> 170
125
- ```
126
-
127
- #### Defer (EventMachine)
128
-
129
- ```ruby
130
- require 'concurrent'
131
-
132
- Concurrent::Defer.new{ "Jerry D'Antonio" }.
133
- then{|result| puts "Hello, #{result}!" }.
134
- rescue{|ex| puts ex.message }.
135
- go
136
-
137
- #=> Hello, Jerry D'Antonio!
138
-
139
- operation = proc{ raise StandardError.new('Boom!') }
140
- callback = proc{|result| puts result }
141
- errorback = proc{|ex| puts ex.message }
142
- defer(operation, callback, errorback)
143
- sleep(0.1)
144
-
145
- #=> "Boom!"
146
- ```
147
-
148
- #### Future (Clojure)
149
-
150
- ```ruby
151
- require 'concurrent'
152
-
153
- count = future{ sleep(1); 10 }
154
- count.state #=> :pending
155
- # do stuff...
156
- count.value #=> 10 (after blocking)
157
- deref count #=> 10
158
- ```
159
-
160
- #### Promise (JavaScript)
161
-
162
- ```ruby
163
- require 'concurrent'
164
-
165
- p = promise("Jerry", "D'Antonio"){|a, b| "#{a} #{b}" }.
166
- then{|result| "Hello #{result}." }.
167
- rescue(StandardError){|ex| puts "Boom!" }.
168
- then{|result| "#{result} Would you like to play a game?"}
169
- sleep(1)
170
- p.value #=> "Hello Jerry D'Antonio. Would you like to play a game?"
171
- ```
172
-
173
- #### Thread Pools
174
-
175
- ```ruby
176
- require 'concurrent'
177
-
178
- pool = Concurrent::FixedThreadPool.new(10)
179
- @expected = 0
180
- pool.post{ sleep(0.5); @expected += 100 }
181
- pool.post{ sleep(0.5); @expected += 100 }
182
- pool.post{ sleep(0.5); @expected += 100 }
183
- @expected #=> nil
184
- sleep(1)
185
- @expected #=> 300
186
-
187
- pool = Concurrent::CachedThreadPool.new
188
- @expected = 0
189
- pool << proc{ sleep(0.5); @expected += 10 }
190
- pool << proc{ sleep(0.5); @expected += 10 }
191
- pool << proc{ sleep(0.5); @expected += 10 }
192
- @expected #=> 0
193
- sleep(1)
194
- @expected #=> 30
195
- ```
196
-
197
- ## Copyright
198
-
199
- *Concurrent Ruby* is Copyright &copy; 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
200
- It is free software and may be redistributed under the terms specified in the LICENSE file.
201
-
202
- ## License
203
-
204
- Released under the MIT license.
205
-
206
- http://www.opensource.org/licenses/mit-license.php
207
-
208
- > Permission is hereby granted, free of charge, to any person obtaining a copy
209
- > of this software and associated documentation files (the "Software"), to deal
210
- > in the Software without restriction, including without limitation the rights
211
- > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
212
- > copies of the Software, and to permit persons to whom the Software is
213
- > furnished to do so, subject to the following conditions:
214
- >
215
- > The above copyright notice and this permission notice shall be included in
216
- > all copies or substantial portions of the Software.
217
- >
218
- > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
219
- > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
220
- > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
221
- > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
222
- > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
223
- > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
224
- > 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
+ This library is optimized for and tested under MRI Ruby 1.9.x and 2.0. It makes heavy use of Fibers and is designed
67
+ to work in concert with MRI's Global Interpreter Lock (GIL). In fact, there are parts of the code that are optimized
68
+ based on the assumption that there *is* a GIL. [JRuby](http://jruby.org/) does not have a GIL and it's implementation of Fibers is
69
+ broken. Therefore I cannot recommend using this library with JRuby. But that's OK. JRuby runs on the JVM and
70
+ has access to many world-class concurrency libraries. Two examples are
71
+ [java.util.concurrent](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html)
72
+ and [Akka](http://akka.io/). Honestly, if you are running JRuby you're probably better of using those
73
+ libraries than this gem. I don't know much about [Rubinius](http://rubini.us/) but I understand that it doesn't
74
+ have a GIL, either. If that's the case then I don't recommend using this gem with Rubinius, either.
75
+
76
+ ### Install
77
+
78
+ ```shell
79
+ gem install concurrent-ruby
80
+ ```
81
+
82
+ or add the following line to Gemfile:
83
+
84
+ ```ruby
85
+ gem 'concurrent-ruby'
86
+ ```
87
+
88
+ and run `bundle install` from your shell.
89
+
90
+ Once you've installed the gem you must `require` it in your project:
91
+
92
+ ```ruby
93
+ require 'concurrent'
94
+ ```
95
+
96
+ ### Kernel Methods
97
+
98
+ Many Ruby developers consider it bad form to add function to the global (Kernel) namespace.
99
+ I don't necessarily agree. If the function acts like a low-level feature of the language
100
+ I think it is OK to add the method to the `Kernel` module. To support my personal programming
101
+ style I have chosen to implement `Kernel` methods to instance many of the objects in this
102
+ library. Out of respect for the larger Ruby community I have made these methods optional.
103
+ They are not imported with the normal `require 'concurrent'` directive. To import these
104
+ functions you must import the `concurrent/functions` library.
105
+
106
+ ```ruby
107
+ require 'concurrent'
108
+ score = agent(10) #=> NoMethodError: undefined method `agent' for main:Object
109
+
110
+ require 'concurrent/functions'
111
+ score = agent(10) #=> #<Concurrent::Agent:0x35b2b28 ...
112
+ score.value #=> 10
113
+ ```
114
+
115
+ ### Examples
116
+
117
+ For complete examples, see the specific documentation linked above. Below are a few examples to whet your appetite.
118
+
119
+ #### Goroutine (Go)
120
+
121
+ ```ruby
122
+ require 'concurrent'
123
+
124
+ @expected = nil
125
+ go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
126
+ sleep(0.1)
127
+ @expected #=> [3, 2, 1]
128
+ ```
129
+
130
+ #### Agent (Clojure)
131
+
132
+ ```ruby
133
+ require 'concurrent'
134
+ require 'concurrent/functions'
135
+
136
+ score = agent(10)
137
+ score.value #=> 10
138
+
139
+ score << proc{|current| current + 100 }
140
+ sleep(0.1)
141
+ score.value #=> 110
142
+
143
+ score << proc{|current| current * 2 }
144
+ sleep(0.1)
145
+ deref score #=> 220
146
+
147
+ score << proc{|current| current - 50 }
148
+ sleep(0.1)
149
+ score.value #=> 170
150
+ ```
151
+
152
+ #### Defer (EventMachine)
153
+
154
+ ```ruby
155
+ require 'concurrent'
156
+ require 'concurrent/functions'
157
+
158
+ Concurrent::Defer.new{ "Jerry D'Antonio" }.
159
+ then{|result| puts "Hello, #{result}!" }.
160
+ rescue{|ex| puts ex.message }.
161
+ go
162
+
163
+ #=> Hello, Jerry D'Antonio!
164
+
165
+ operation = proc{ raise StandardError.new('Boom!') }
166
+ callback = proc{|result| puts result }
167
+ errorback = proc{|ex| puts ex.message }
168
+ defer(operation, callback, errorback)
169
+ sleep(0.1)
170
+
171
+ #=> "Boom!"
172
+ ```
173
+
174
+ #### Future (Clojure)
175
+
176
+ ```ruby
177
+ require 'concurrent'
178
+ require 'concurrent/functions'
179
+
180
+ count = future{ sleep(1); 10 }
181
+ count.state #=> :pending
182
+ # do stuff...
183
+ count.value #=> 10 (after blocking)
184
+ deref count #=> 10
185
+ ```
186
+
187
+ #### Promise (JavaScript)
188
+
189
+ ```ruby
190
+ require 'concurrent'
191
+ require 'concurrent/functions'
192
+
193
+ p = promise("Jerry", "D'Antonio"){|a, b| "#{a} #{b}" }.
194
+ then{|result| "Hello #{result}." }.
195
+ rescue(StandardError){|ex| puts "Boom!" }.
196
+ then{|result| "#{result} Would you like to play a game?"}
197
+ sleep(1)
198
+ p.value #=> "Hello Jerry D'Antonio. Would you like to play a game?"
199
+ ```
200
+
201
+ #### Thread Pools
202
+
203
+ ```ruby
204
+ require 'concurrent'
205
+
206
+ pool = Concurrent::FixedThreadPool.new(10)
207
+ @expected = 0
208
+ pool.post{ sleep(0.5); @expected += 100 }
209
+ pool.post{ sleep(0.5); @expected += 100 }
210
+ pool.post{ sleep(0.5); @expected += 100 }
211
+ @expected #=> nil
212
+ sleep(1)
213
+ @expected #=> 300
214
+
215
+ pool = Concurrent::CachedThreadPool.new
216
+ @expected = 0
217
+ pool << proc{ sleep(0.5); @expected += 10 }
218
+ pool << proc{ sleep(0.5); @expected += 10 }
219
+ pool << proc{ sleep(0.5); @expected += 10 }
220
+ @expected #=> 0
221
+ sleep(1)
222
+ @expected #=> 30
223
+ ```
224
+
225
+ #### Executor
226
+
227
+ ```ruby
228
+ require 'concurrent'
229
+
230
+ ec = Concurrent::Executor.run('Foo'){ puts 'Boom!' }
231
+
232
+ ec.name #=> "Foo"
233
+ ec.execution_interval #=> 60 == Concurrent::Executor::EXECUTION_INTERVAL
234
+ ec.timeout_interval #=> 30 == Concurrent::Executor::TIMEOUT_INTERVAL
235
+ ec.status #=> "sleep"
236
+
237
+ # wait 60 seconds...
238
+ #=> 'Boom!'
239
+ #=> ' INFO (2013-08-02 23:20:15) Foo: execution completed successfully'
240
+
241
+ ec.kill #=> true
242
+ ```
243
+
244
+ ## Contributing
245
+
246
+ 1. Fork it
247
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
248
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
249
+ 4. Push to the branch (`git push origin my-new-feature`)
250
+ 5. Create new Pull Request
251
+
252
+ ## Copyright
253
+
254
+ *Concurrent Ruby* is Copyright &copy; 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
255
+ It is free software and may be redistributed under the terms specified in the LICENSE file.
256
+
257
+ ## License
258
+
259
+ Released under the MIT license.
260
+
261
+ http://www.opensource.org/licenses/mit-license.php
262
+
263
+ > Permission is hereby granted, free of charge, to any person obtaining a copy
264
+ > of this software and associated documentation files (the "Software"), to deal
265
+ > in the Software without restriction, including without limitation the rights
266
+ > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
267
+ > copies of the Software, and to permit persons to whom the Software is
268
+ > furnished to do so, subject to the following conditions:
269
+ >
270
+ > The above copyright notice and this permission notice shall be included in
271
+ > all copies or substantial portions of the Software.
272
+ >
273
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
274
+ > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
275
+ > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
276
+ > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
277
+ > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
278
+ > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
279
+ > THE SOFTWARE.