concurrent-ruby 0.1.0 → 0.1.1.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -21
- data/README.md +279 -224
- data/lib/concurrent.rb +27 -20
- data/lib/concurrent/agent.rb +106 -130
- data/lib/concurrent/cached_thread_pool.rb +130 -122
- data/lib/concurrent/defer.rb +67 -69
- data/lib/concurrent/drb_async_demux.rb +72 -0
- data/lib/concurrent/event.rb +60 -60
- data/lib/concurrent/event_machine_defer_proxy.rb +23 -23
- data/lib/concurrent/executor.rb +87 -0
- data/lib/concurrent/fixed_thread_pool.rb +89 -89
- data/lib/concurrent/functions.rb +120 -0
- data/lib/concurrent/future.rb +52 -42
- data/lib/concurrent/global_thread_pool.rb +3 -3
- data/lib/concurrent/goroutine.rb +29 -25
- data/lib/concurrent/obligation.rb +67 -121
- data/lib/concurrent/promise.rb +172 -194
- data/lib/concurrent/reactor.rb +162 -0
- data/lib/concurrent/smart_mutex.rb +66 -0
- data/lib/concurrent/tcp_sync_demux.rb +96 -0
- data/lib/concurrent/thread_pool.rb +65 -61
- data/lib/concurrent/utilities.rb +34 -0
- data/lib/concurrent/version.rb +3 -3
- data/lib/concurrent_ruby.rb +1 -1
- data/md/agent.md +123 -123
- data/md/defer.md +174 -174
- data/md/event.md +32 -32
- data/md/executor.md +176 -0
- data/md/future.md +83 -83
- data/md/goroutine.md +52 -52
- data/md/obligation.md +32 -32
- data/md/promise.md +225 -225
- data/md/thread_pool.md +197 -197
- data/spec/concurrent/agent_spec.rb +376 -405
- data/spec/concurrent/cached_thread_pool_spec.rb +112 -112
- data/spec/concurrent/defer_spec.rb +209 -199
- data/spec/concurrent/event_machine_defer_proxy_spec.rb +250 -246
- data/spec/concurrent/event_spec.rb +134 -134
- data/spec/concurrent/executor_spec.rb +146 -0
- data/spec/concurrent/fixed_thread_pool_spec.rb +84 -84
- data/spec/concurrent/functions_spec.rb +57 -0
- data/spec/concurrent/future_spec.rb +125 -115
- data/spec/concurrent/goroutine_spec.rb +67 -52
- data/spec/concurrent/obligation_shared.rb +121 -121
- data/spec/concurrent/promise_spec.rb +299 -310
- data/spec/concurrent/smart_mutex_spec.rb +234 -0
- data/spec/concurrent/thread_pool_shared.rb +209 -209
- data/spec/concurrent/utilities_spec.rb +74 -0
- data/spec/spec_helper.rb +21 -19
- metadata +38 -14
- checksums.yaml +0 -7
data/md/event.md
CHANGED
@@ -1,32 +1,32 @@
|
|
1
|
-
# Event
|
2
|
-
|
3
|
-
TBD...
|
4
|
-
|
5
|
-
## Copyright
|
6
|
-
|
7
|
-
*Concurrent Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
|
8
|
-
It is free software and may be redistributed under the terms specified in the LICENSE file.
|
9
|
-
|
10
|
-
## License
|
11
|
-
|
12
|
-
Released under the MIT license.
|
13
|
-
|
14
|
-
http://www.opensource.org/licenses/mit-license.php
|
15
|
-
|
16
|
-
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
17
|
-
> of this software and associated documentation files (the "Software"), to deal
|
18
|
-
> in the Software without restriction, including without limitation the rights
|
19
|
-
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
20
|
-
> copies of the Software, and to permit persons to whom the Software is
|
21
|
-
> furnished to do so, subject to the following conditions:
|
22
|
-
>
|
23
|
-
> The above copyright notice and this permission notice shall be included in
|
24
|
-
> all copies or substantial portions of the Software.
|
25
|
-
>
|
26
|
-
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
27
|
-
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
28
|
-
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
29
|
-
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
30
|
-
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
31
|
-
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
32
|
-
> THE SOFTWARE.
|
1
|
+
# Event
|
2
|
+
|
3
|
+
TBD...
|
4
|
+
|
5
|
+
## Copyright
|
6
|
+
|
7
|
+
*Concurrent Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
|
8
|
+
It is free software and may be redistributed under the terms specified in the LICENSE file.
|
9
|
+
|
10
|
+
## License
|
11
|
+
|
12
|
+
Released under the MIT license.
|
13
|
+
|
14
|
+
http://www.opensource.org/licenses/mit-license.php
|
15
|
+
|
16
|
+
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
17
|
+
> of this software and associated documentation files (the "Software"), to deal
|
18
|
+
> in the Software without restriction, including without limitation the rights
|
19
|
+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
20
|
+
> copies of the Software, and to permit persons to whom the Software is
|
21
|
+
> furnished to do so, subject to the following conditions:
|
22
|
+
>
|
23
|
+
> The above copyright notice and this permission notice shall be included in
|
24
|
+
> all copies or substantial portions of the Software.
|
25
|
+
>
|
26
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
27
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
28
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
29
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
30
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
31
|
+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
32
|
+
> THE SOFTWARE.
|
data/md/executor.md
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# Being of Sound Mind
|
2
|
+
|
3
|
+
A very common currency pattern is to run a thread that performs a task at regular
|
4
|
+
intervals. The thread that peforms the task sleeps for the given interval then
|
5
|
+
waked up and performs the task. Later, rinse, repeat... This pattern causes two
|
6
|
+
problems. First, it is difficult to test the business logic of the task becuse the
|
7
|
+
task itself is tightly couple with the threading. Second, an exception in the task
|
8
|
+
can cause the entire thread to abend. In a long-running application where the task
|
9
|
+
thread is intended to run for days/weeks/years a crashed task thread can pose a real
|
10
|
+
problem. The `Executor` class alleviates both problems.
|
11
|
+
|
12
|
+
When an executor is launched it starts a thread for monitoring the execution interval.
|
13
|
+
The executor thread does not perform the task, however. Instead, the executor
|
14
|
+
launches the task on a separat thread. The advantage of this approach is that if
|
15
|
+
the task crashes it will only kill the task thread, not the executor thread. The
|
16
|
+
executor thread can then log the success or failure of the task. The executor
|
17
|
+
can even be configured with a timeout value allowing it to kill a task that runs
|
18
|
+
to long and then log the error.
|
19
|
+
|
20
|
+
One other advantage of the `Executor` class is that it forces the bsiness logic to
|
21
|
+
be completely decoupled from the threading logic. The business logic can be tested
|
22
|
+
separately then passed to the an executor for scheduling and running.
|
23
|
+
|
24
|
+
Unlike some of the others concurrency objects in the library, executors do not
|
25
|
+
run on the global. In my experience the types of tasks that will benefit from
|
26
|
+
the `Executor` class tend to also be long running. For this reason they get their
|
27
|
+
own thread every time the task is executed.
|
28
|
+
|
29
|
+
## ExecutionContext
|
30
|
+
|
31
|
+
When an executor is run the return value is an `ExecutionContext` object. An
|
32
|
+
`ExecutionContext` object has several attribute readers (`#name`, `#execution_interval`,
|
33
|
+
and `#timeout_interval`). It also provides several `Thread` operations which can
|
34
|
+
be performed against the internal thread. These include `#status`, `#join`, and
|
35
|
+
`kill`.
|
36
|
+
|
37
|
+
## Custom Logging
|
38
|
+
|
39
|
+
An executor will write a log message to standard out at the completion of every
|
40
|
+
task run. When the task is successful the log message is tagged at the `:info`
|
41
|
+
level. When the task times out the log message is tagged at the `warn` level.
|
42
|
+
When the task fails tocomplete (most likely because of exception) the log
|
43
|
+
message is tagged at the `error` level.
|
44
|
+
|
45
|
+
The default logging behavior can be overridden by passing a `proc` to the executor
|
46
|
+
on creation. The block will be passes three (3) arguments every time it is run:
|
47
|
+
executor `name`, log `level`, and the log `msg` (message). The `proc` can do
|
48
|
+
whatever it wanst with these arguments.
|
49
|
+
|
50
|
+
## Examples
|
51
|
+
|
52
|
+
A basic example:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
require 'concurrent'
|
56
|
+
|
57
|
+
ec = Concurrent::Executor.run('Foo'){ puts 'Boom!' }
|
58
|
+
|
59
|
+
ec.name #=> "Foo"
|
60
|
+
ec.execution_interval #=> 60 == Concurrent::Executor::EXECUTION_INTERVAL
|
61
|
+
ec.timeout_interval #=> 30 == Concurrent::Executor::TIMEOUT_INTERVAL
|
62
|
+
ec.status #=> "sleep"
|
63
|
+
|
64
|
+
# wait 60 seconds...
|
65
|
+
#=> 'Boom!'
|
66
|
+
#=> ' INFO (2013-08-02 23:20:15) Foo: execution completed successfully'
|
67
|
+
|
68
|
+
ec.kill #=> true
|
69
|
+
```
|
70
|
+
|
71
|
+
Both the execution_interval and the timeout_interval can be configured:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
ec = Concurrent::Executor.run('Foo', execution_interval: 5, timeout_interval: 5) do
|
75
|
+
puts 'Boom!'
|
76
|
+
end
|
77
|
+
|
78
|
+
ec.execution_interval #=> 5
|
79
|
+
ec.timeout_interval #=> 5
|
80
|
+
```
|
81
|
+
|
82
|
+
A simple example with timeout and task exception:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
ec = Concurrent::Executor.run('Foo', execution_interval: 1, timeout_interval: 1){ sleep(10) }
|
86
|
+
|
87
|
+
#=> WARN (2013-08-02 23:45:26) Foo: execution timed out after 1 seconds
|
88
|
+
#=> WARN (2013-08-02 23:45:28) Foo: execution timed out after 1 seconds
|
89
|
+
#=> WARN (2013-08-02 23:45:30) Foo: execution timed out after 1 seconds
|
90
|
+
|
91
|
+
ec = Concurrent::Executor.run('Foo', execution_interval: 1){ raise StandardError }
|
92
|
+
|
93
|
+
#=> ERROR (2013-08-02 23:47:31) Foo: execution failed with error 'StandardError'
|
94
|
+
#=> ERROR (2013-08-02 23:47:32) Foo: execution failed with error 'StandardError'
|
95
|
+
#=> ERROR (2013-08-02 23:47:33) Foo: execution failed with error 'StandardError'
|
96
|
+
```
|
97
|
+
|
98
|
+
For custom logging, simply provide a `proc` when creating an executor:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
file_logger = proc do |name, level, msg|
|
102
|
+
open('executor.log', 'a') do |f|
|
103
|
+
f << ("%5s (%s) %s: %s\n" % [level.upcase, Time.now.strftime("%F %T"), name, msg])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
ec = Concurrent::Executor.run('Foo', execution_interval: 5, logger: file_logger) do
|
108
|
+
puts 'Boom!'
|
109
|
+
end
|
110
|
+
|
111
|
+
# the log file contains
|
112
|
+
# INFO (2013-08-02 23:30:19) Foo: execution completed successfully
|
113
|
+
# INFO (2013-08-02 23:30:24) Foo: execution completed successfully
|
114
|
+
# INFO (2013-08-02 23:30:29) Foo: execution completed successfully
|
115
|
+
# INFO (2013-08-02 23:30:34) Foo: execution completed successfully
|
116
|
+
# INFO (2013-08-02 23:30:39) Foo: execution completed successfully
|
117
|
+
# INFO (2013-08-02 23:30:44) Foo: execution completed successfully
|
118
|
+
```
|
119
|
+
|
120
|
+
It is also possible to access the default stdout logger from within a logger `proc`:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
file_logger = proc do |name, level, msg|
|
124
|
+
Concurrent::Executor::STDOUT_LOGGER.call(name, level, msg)
|
125
|
+
open('executor.log', 'a') do |f|
|
126
|
+
f << ("%5s (%s) %s: %s\n" % [level.upcase, Time.now.strftime("%F %T"), name, msg])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
ec = Concurrent::Executor.run('Foo', execution_interval: 5, logger: file_logger) do
|
131
|
+
puts 'Boom!'
|
132
|
+
end
|
133
|
+
|
134
|
+
# wait...
|
135
|
+
|
136
|
+
#=> Boom!
|
137
|
+
#=> INFO (2013-08-02 23:40:49) Foo: execution completed successfully
|
138
|
+
#=> Boom!
|
139
|
+
#=> INFO (2013-08-02 23:40:54) Foo: execution completed successfully
|
140
|
+
#=> Boom!
|
141
|
+
#=> INFO (2013-08-02 23:40:59) Foo: execution completed successfully
|
142
|
+
|
143
|
+
# and the log file contains
|
144
|
+
# INFO (2013-08-02 23:39:52) Foo: execution completed successfully
|
145
|
+
# INFO (2013-08-02 23:39:57) Foo: execution completed successfully
|
146
|
+
# INFO (2013-08-02 23:40:49) Foo: execution completed successfully
|
147
|
+
```
|
148
|
+
|
149
|
+
## Copyright
|
150
|
+
|
151
|
+
*Concurrent Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
|
152
|
+
It is free software and may be redistributed under the terms specified in the LICENSE file.
|
153
|
+
|
154
|
+
## License
|
155
|
+
|
156
|
+
Released under the MIT license.
|
157
|
+
|
158
|
+
http://www.opensource.org/licenses/mit-license.php
|
159
|
+
|
160
|
+
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
161
|
+
> of this software and associated documentation files (the "Software"), to deal
|
162
|
+
> in the Software without restriction, including without limitation the rights
|
163
|
+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
164
|
+
> copies of the Software, and to permit persons to whom the Software is
|
165
|
+
> furnished to do so, subject to the following conditions:
|
166
|
+
>
|
167
|
+
> The above copyright notice and this permission notice shall be included in
|
168
|
+
> all copies or substantial portions of the Software.
|
169
|
+
>
|
170
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
171
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
172
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
173
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
174
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
175
|
+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
176
|
+
> THE SOFTWARE.
|
data/md/future.md
CHANGED
@@ -1,83 +1,83 @@
|
|
1
|
-
# We're Sending You Back to the Future!
|
2
|
-
|
3
|
-
Futures are inspired by [Clojure's](http://clojure.org/) [future](http://clojuredocs.org/clojure_core/clojure.core/future) keyword.
|
4
|
-
A future represents a promise to complete an action at some time in the future. The action is atomic and permanent.
|
5
|
-
The idea behind a future is to send an action off for asynchronous operation, do other stuff, then return and
|
6
|
-
retrieve the result of the async operation at a later time. Futures run on the global thread pool (see below).
|
7
|
-
|
8
|
-
Futures have three possible states: *pending*, *rejected*, and *fulfilled*. When a future is created it is set
|
9
|
-
to *pending* and will remain in that state until processing is complete. A completed future is either *rejected*,
|
10
|
-
indicating that an exception was thrown during processing, or *fulfilled*, indicating succedd. If a future is
|
11
|
-
*fulfilled* its `value` will be updated to reflect the result of the operation. If *rejected* the `reason` will
|
12
|
-
be updated with a reference to the thrown exception. The predicate methods `pending?`, `rejected`, and `fulfilled?`
|
13
|
-
can be called at any time to obtain the state of the future, as can the `state` method, which returns a symbol.
|
14
|
-
|
15
|
-
Retrieving the value of a future is done through the `value` (alias: `deref`) method. Obtaining the value of
|
16
|
-
a future is a potentially blocking operation. When a future is *rejected* a call to `value` will return `nil`
|
17
|
-
immediately. When a future is *fulfilled* a call to `value` will immediately return the current value.
|
18
|
-
When a future is *pending* a call to `value` will block until the future is either *rejected* or *fulfilled*.
|
19
|
-
A *timeout* value can be passed to `value` to limit how long the call will block. If `nil` the call will
|
20
|
-
block indefinitely. If `0` the call will not block. Any other integer or float value will indicate the
|
21
|
-
maximum number of seconds to block.
|
22
|
-
|
23
|
-
## Examples
|
24
|
-
|
25
|
-
A fulfilled example:
|
26
|
-
|
27
|
-
```ruby
|
28
|
-
require 'concurrent'
|
29
|
-
|
30
|
-
count = Concurrent::Future{ sleep(10); 10 }
|
31
|
-
count.state #=> :pending
|
32
|
-
count.pending? #=> true
|
33
|
-
|
34
|
-
# do stuff...
|
35
|
-
|
36
|
-
count.value(0) #=> nil (does not block)
|
37
|
-
|
38
|
-
count.value #=> 10 (after blocking)
|
39
|
-
count.state #=> :fulfilled
|
40
|
-
count.fulfilled? #=> true
|
41
|
-
deref count #=> 10
|
42
|
-
```
|
43
|
-
|
44
|
-
A rejected example:
|
45
|
-
|
46
|
-
```ruby
|
47
|
-
count = future{ sleep(10); raise StandardError.new("Boom!") }
|
48
|
-
count.state #=> :pending
|
49
|
-
pending?(count) #=> true
|
50
|
-
|
51
|
-
deref(count) #=> nil (after blocking)
|
52
|
-
rejected?(count) #=> true
|
53
|
-
count.reason #=> #<StandardError: Boom!>
|
54
|
-
```
|
55
|
-
|
56
|
-
## Copyright
|
57
|
-
|
58
|
-
*Concurrent Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
|
59
|
-
It is free software and may be redistributed under the terms specified in the LICENSE file.
|
60
|
-
|
61
|
-
## License
|
62
|
-
|
63
|
-
Released under the MIT license.
|
64
|
-
|
65
|
-
http://www.opensource.org/licenses/mit-license.php
|
66
|
-
|
67
|
-
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
68
|
-
> of this software and associated documentation files (the "Software"), to deal
|
69
|
-
> in the Software without restriction, including without limitation the rights
|
70
|
-
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
71
|
-
> copies of the Software, and to permit persons to whom the Software is
|
72
|
-
> furnished to do so, subject to the following conditions:
|
73
|
-
>
|
74
|
-
> The above copyright notice and this permission notice shall be included in
|
75
|
-
> all copies or substantial portions of the Software.
|
76
|
-
>
|
77
|
-
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
78
|
-
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
79
|
-
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
80
|
-
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
81
|
-
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
82
|
-
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
83
|
-
> THE SOFTWARE.
|
1
|
+
# We're Sending You Back to the Future!
|
2
|
+
|
3
|
+
Futures are inspired by [Clojure's](http://clojure.org/) [future](http://clojuredocs.org/clojure_core/clojure.core/future) keyword.
|
4
|
+
A future represents a promise to complete an action at some time in the future. The action is atomic and permanent.
|
5
|
+
The idea behind a future is to send an action off for asynchronous operation, do other stuff, then return and
|
6
|
+
retrieve the result of the async operation at a later time. Futures run on the global thread pool (see below).
|
7
|
+
|
8
|
+
Futures have three possible states: *pending*, *rejected*, and *fulfilled*. When a future is created it is set
|
9
|
+
to *pending* and will remain in that state until processing is complete. A completed future is either *rejected*,
|
10
|
+
indicating that an exception was thrown during processing, or *fulfilled*, indicating succedd. If a future is
|
11
|
+
*fulfilled* its `value` will be updated to reflect the result of the operation. If *rejected* the `reason` will
|
12
|
+
be updated with a reference to the thrown exception. The predicate methods `pending?`, `rejected`, and `fulfilled?`
|
13
|
+
can be called at any time to obtain the state of the future, as can the `state` method, which returns a symbol.
|
14
|
+
|
15
|
+
Retrieving the value of a future is done through the `value` (alias: `deref`) method. Obtaining the value of
|
16
|
+
a future is a potentially blocking operation. When a future is *rejected* a call to `value` will return `nil`
|
17
|
+
immediately. When a future is *fulfilled* a call to `value` will immediately return the current value.
|
18
|
+
When a future is *pending* a call to `value` will block until the future is either *rejected* or *fulfilled*.
|
19
|
+
A *timeout* value can be passed to `value` to limit how long the call will block. If `nil` the call will
|
20
|
+
block indefinitely. If `0` the call will not block. Any other integer or float value will indicate the
|
21
|
+
maximum number of seconds to block.
|
22
|
+
|
23
|
+
## Examples
|
24
|
+
|
25
|
+
A fulfilled example:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'concurrent'
|
29
|
+
|
30
|
+
count = Concurrent::Future{ sleep(10); 10 }
|
31
|
+
count.state #=> :pending
|
32
|
+
count.pending? #=> true
|
33
|
+
|
34
|
+
# do stuff...
|
35
|
+
|
36
|
+
count.value(0) #=> nil (does not block)
|
37
|
+
|
38
|
+
count.value #=> 10 (after blocking)
|
39
|
+
count.state #=> :fulfilled
|
40
|
+
count.fulfilled? #=> true
|
41
|
+
deref count #=> 10
|
42
|
+
```
|
43
|
+
|
44
|
+
A rejected example:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
count = future{ sleep(10); raise StandardError.new("Boom!") }
|
48
|
+
count.state #=> :pending
|
49
|
+
pending?(count) #=> true
|
50
|
+
|
51
|
+
deref(count) #=> nil (after blocking)
|
52
|
+
rejected?(count) #=> true
|
53
|
+
count.reason #=> #<StandardError: Boom!>
|
54
|
+
```
|
55
|
+
|
56
|
+
## Copyright
|
57
|
+
|
58
|
+
*Concurrent Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
|
59
|
+
It is free software and may be redistributed under the terms specified in the LICENSE file.
|
60
|
+
|
61
|
+
## License
|
62
|
+
|
63
|
+
Released under the MIT license.
|
64
|
+
|
65
|
+
http://www.opensource.org/licenses/mit-license.php
|
66
|
+
|
67
|
+
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
68
|
+
> of this software and associated documentation files (the "Software"), to deal
|
69
|
+
> in the Software without restriction, including without limitation the rights
|
70
|
+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
71
|
+
> copies of the Software, and to permit persons to whom the Software is
|
72
|
+
> furnished to do so, subject to the following conditions:
|
73
|
+
>
|
74
|
+
> The above copyright notice and this permission notice shall be included in
|
75
|
+
> all copies or substantial portions of the Software.
|
76
|
+
>
|
77
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
78
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
79
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
80
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
81
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
82
|
+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
83
|
+
> THE SOFTWARE.
|
data/md/goroutine.md
CHANGED
@@ -1,52 +1,52 @@
|
|
1
|
-
# Go, Go, Gadget Goroutine!
|
2
|
-
|
3
|
-
A goroutine is the simplest of the concurrency utilities in this library. It is inspired by
|
4
|
-
[Go's](http://golang.org/) [goroutines](https://gobyexample.com/goroutines) and
|
5
|
-
[Erlang's](http://www.erlang.org/) [spawn](http://erlangexamples.com/tag/spawn/) keyword. The
|
6
|
-
`go` function is nothing more than a simple way to send a block to the global thread pool (see below)
|
7
|
-
for processing.
|
8
|
-
|
9
|
-
## Examples
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
require 'concurrent'
|
13
|
-
|
14
|
-
@expected = nil
|
15
|
-
|
16
|
-
go(1, 2, 3){|a, b, c| sleep(1); @expected = [c, b, a] }
|
17
|
-
|
18
|
-
sleep(0.1)
|
19
|
-
@expected #=> nil
|
20
|
-
|
21
|
-
sleep(2)
|
22
|
-
@expected #=> [3, 2, 1]
|
23
|
-
```
|
24
|
-
|
25
|
-
## Copyright
|
26
|
-
|
27
|
-
*Concurrent Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
|
28
|
-
It is free software and may be redistributed under the terms specified in the LICENSE file.
|
29
|
-
|
30
|
-
## License
|
31
|
-
|
32
|
-
Released under the MIT license.
|
33
|
-
|
34
|
-
http://www.opensource.org/licenses/mit-license.php
|
35
|
-
|
36
|
-
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
37
|
-
> of this software and associated documentation files (the "Software"), to deal
|
38
|
-
> in the Software without restriction, including without limitation the rights
|
39
|
-
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
40
|
-
> copies of the Software, and to permit persons to whom the Software is
|
41
|
-
> furnished to do so, subject to the following conditions:
|
42
|
-
>
|
43
|
-
> The above copyright notice and this permission notice shall be included in
|
44
|
-
> all copies or substantial portions of the Software.
|
45
|
-
>
|
46
|
-
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
47
|
-
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
48
|
-
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
49
|
-
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
50
|
-
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
51
|
-
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
52
|
-
> THE SOFTWARE.
|
1
|
+
# Go, Go, Gadget Goroutine!
|
2
|
+
|
3
|
+
A goroutine is the simplest of the concurrency utilities in this library. It is inspired by
|
4
|
+
[Go's](http://golang.org/) [goroutines](https://gobyexample.com/goroutines) and
|
5
|
+
[Erlang's](http://www.erlang.org/) [spawn](http://erlangexamples.com/tag/spawn/) keyword. The
|
6
|
+
`go` function is nothing more than a simple way to send a block to the global thread pool (see below)
|
7
|
+
for processing.
|
8
|
+
|
9
|
+
## Examples
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'concurrent'
|
13
|
+
|
14
|
+
@expected = nil
|
15
|
+
|
16
|
+
go(1, 2, 3){|a, b, c| sleep(1); @expected = [c, b, a] }
|
17
|
+
|
18
|
+
sleep(0.1)
|
19
|
+
@expected #=> nil
|
20
|
+
|
21
|
+
sleep(2)
|
22
|
+
@expected #=> [3, 2, 1]
|
23
|
+
```
|
24
|
+
|
25
|
+
## Copyright
|
26
|
+
|
27
|
+
*Concurrent Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
|
28
|
+
It is free software and may be redistributed under the terms specified in the LICENSE file.
|
29
|
+
|
30
|
+
## License
|
31
|
+
|
32
|
+
Released under the MIT license.
|
33
|
+
|
34
|
+
http://www.opensource.org/licenses/mit-license.php
|
35
|
+
|
36
|
+
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
37
|
+
> of this software and associated documentation files (the "Software"), to deal
|
38
|
+
> in the Software without restriction, including without limitation the rights
|
39
|
+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
40
|
+
> copies of the Software, and to permit persons to whom the Software is
|
41
|
+
> furnished to do so, subject to the following conditions:
|
42
|
+
>
|
43
|
+
> The above copyright notice and this permission notice shall be included in
|
44
|
+
> all copies or substantial portions of the Software.
|
45
|
+
>
|
46
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
47
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
48
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
49
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
50
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
51
|
+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
52
|
+
> THE SOFTWARE.
|