concurrent-ruby 0.5.0 → 0.6.0.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.
- checksums.yaml +4 -4
- data/README.md +88 -77
- data/lib/concurrent.rb +17 -2
- data/lib/concurrent/actor.rb +17 -0
- data/lib/concurrent/actor_context.rb +31 -0
- data/lib/concurrent/actor_ref.rb +39 -0
- data/lib/concurrent/agent.rb +12 -3
- data/lib/concurrent/async.rb +290 -0
- data/lib/concurrent/atomic.rb +5 -9
- data/lib/concurrent/cached_thread_pool.rb +39 -137
- data/lib/concurrent/channel/blocking_ring_buffer.rb +60 -0
- data/lib/concurrent/channel/buffered_channel.rb +83 -0
- data/lib/concurrent/channel/channel.rb +11 -0
- data/lib/concurrent/channel/probe.rb +19 -0
- data/lib/concurrent/channel/ring_buffer.rb +54 -0
- data/lib/concurrent/channel/unbuffered_channel.rb +34 -0
- data/lib/concurrent/channel/waitable_list.rb +38 -0
- data/lib/concurrent/configuration.rb +92 -0
- data/lib/concurrent/dataflow.rb +9 -3
- data/lib/concurrent/delay.rb +88 -0
- data/lib/concurrent/exchanger.rb +31 -0
- data/lib/concurrent/fixed_thread_pool.rb +28 -122
- data/lib/concurrent/future.rb +10 -5
- data/lib/concurrent/immediate_executor.rb +3 -2
- data/lib/concurrent/ivar.rb +2 -1
- data/lib/concurrent/java_cached_thread_pool.rb +45 -0
- data/lib/concurrent/java_fixed_thread_pool.rb +37 -0
- data/lib/concurrent/java_thread_pool_executor.rb +194 -0
- data/lib/concurrent/per_thread_executor.rb +23 -0
- data/lib/concurrent/postable.rb +2 -0
- data/lib/concurrent/processor_count.rb +125 -0
- data/lib/concurrent/promise.rb +42 -18
- data/lib/concurrent/ruby_cached_thread_pool.rb +37 -0
- data/lib/concurrent/ruby_fixed_thread_pool.rb +31 -0
- data/lib/concurrent/ruby_thread_pool_executor.rb +268 -0
- data/lib/concurrent/ruby_thread_pool_worker.rb +69 -0
- data/lib/concurrent/simple_actor_ref.rb +124 -0
- data/lib/concurrent/thread_local_var.rb +1 -1
- data/lib/concurrent/thread_pool_executor.rb +30 -0
- data/lib/concurrent/timer_task.rb +13 -10
- data/lib/concurrent/tvar.rb +212 -0
- data/lib/concurrent/utilities.rb +1 -0
- data/lib/concurrent/version.rb +1 -1
- data/spec/concurrent/actor_context_spec.rb +37 -0
- data/spec/concurrent/actor_ref_shared.rb +313 -0
- data/spec/concurrent/actor_spec.rb +9 -1
- data/spec/concurrent/agent_spec.rb +97 -96
- data/spec/concurrent/async_spec.rb +320 -0
- data/spec/concurrent/cached_thread_pool_shared.rb +137 -0
- data/spec/concurrent/channel/blocking_ring_buffer_spec.rb +149 -0
- data/spec/concurrent/channel/buffered_channel_spec.rb +151 -0
- data/spec/concurrent/channel/channel_spec.rb +37 -0
- data/spec/concurrent/channel/probe_spec.rb +49 -0
- data/spec/concurrent/channel/ring_buffer_spec.rb +126 -0
- data/spec/concurrent/channel/unbuffered_channel_spec.rb +132 -0
- data/spec/concurrent/configuration_spec.rb +134 -0
- data/spec/concurrent/dataflow_spec.rb +109 -27
- data/spec/concurrent/delay_spec.rb +77 -0
- data/spec/concurrent/exchanger_spec.rb +66 -0
- data/spec/concurrent/fixed_thread_pool_shared.rb +136 -0
- data/spec/concurrent/future_spec.rb +60 -51
- data/spec/concurrent/global_thread_pool_shared.rb +33 -0
- data/spec/concurrent/immediate_executor_spec.rb +4 -25
- data/spec/concurrent/ivar_spec.rb +36 -23
- data/spec/concurrent/java_cached_thread_pool_spec.rb +64 -0
- data/spec/concurrent/java_fixed_thread_pool_spec.rb +64 -0
- data/spec/concurrent/java_thread_pool_executor_spec.rb +71 -0
- data/spec/concurrent/obligation_shared.rb +32 -20
- data/spec/concurrent/{global_thread_pool_spec.rb → per_thread_executor_spec.rb} +9 -13
- data/spec/concurrent/processor_count_spec.rb +20 -0
- data/spec/concurrent/promise_spec.rb +29 -41
- data/spec/concurrent/ruby_cached_thread_pool_spec.rb +69 -0
- data/spec/concurrent/ruby_fixed_thread_pool_spec.rb +39 -0
- data/spec/concurrent/ruby_thread_pool_executor_spec.rb +183 -0
- data/spec/concurrent/simple_actor_ref_spec.rb +219 -0
- data/spec/concurrent/thread_pool_class_cast_spec.rb +40 -0
- data/spec/concurrent/thread_pool_executor_shared.rb +155 -0
- data/spec/concurrent/thread_pool_shared.rb +98 -36
- data/spec/concurrent/tvar_spec.rb +137 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/functions.rb +4 -0
- metadata +85 -20
- data/lib/concurrent/cached_thread_pool/worker.rb +0 -91
- data/lib/concurrent/channel.rb +0 -63
- data/lib/concurrent/fixed_thread_pool/worker.rb +0 -54
- data/lib/concurrent/global_thread_pool.rb +0 -42
- data/spec/concurrent/cached_thread_pool_spec.rb +0 -101
- data/spec/concurrent/channel_spec.rb +0 -86
- data/spec/concurrent/fixed_thread_pool_spec.rb +0 -92
- data/spec/concurrent/uses_global_thread_pool_shared.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e4a4e756232abaffd4ca55c37e049af25f9884a
|
4
|
+
data.tar.gz: 9345ebbf4f1a05e1c5b0eccd8df0d111407c293e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e5b34f7f631e3cb76248674f8cae5b1bee56c8485c71f32cff53d2625fb5475d84e7ff0b1f07272efbfe860652f391ea5f1078652e0c47edc2117a5099152e1
|
7
|
+
data.tar.gz: 5c736c6a669fd952268275f9b1e802f32eac4dc78386df90b871f1bb6dc66985b9b5e7e2046ce5bf81235608c1bc3340a1dcbd49573fb65d8cacf8b6b53f3d06
|
data/README.md
CHANGED
@@ -1,26 +1,37 @@
|
|
1
1
|
# Concurrent Ruby
|
2
2
|
[](http://badge.fury.io/rb/concurrent-ruby) [](https://travis-ci.org/jdantonio/concurrent-ruby?branch=master) [](https://coveralls.io/r/jdantonio/concurrent-ruby) [](https://codeclimate.com/github/jdantonio/concurrent-ruby) [](http://inch-pages.github.io/github/jdantonio/concurrent-ruby) [](https://gemnasium.com/jdantonio/concurrent-ruby)
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
<table>
|
5
|
+
<tr>
|
6
|
+
<td align="left" valign="top">
|
7
|
+
<p>
|
6
8
|
Modern concurrency tools for Ruby. Inspired by
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
<a href="http://www.erlang.org/doc/reference_manual/processes.html">Erlang</a>,
|
10
|
+
<a href="http://clojure.org/concurrent_programming">Clojure</a>,
|
11
|
+
<a href="http://www.scala-lang.org/api/current/index.html#scala.actors.Actor">Scala</a>,
|
12
|
+
<a href="http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell">Haskell</a>,
|
13
|
+
<a href="http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx">F#</a>,
|
14
|
+
<a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx">C#</a>,
|
15
|
+
<a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html">Java</a>,
|
14
16
|
and classic concurrency patterns.
|
15
|
-
|
17
|
+
</p>
|
18
|
+
<p>
|
16
19
|
The design goals of this gem are:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
<ul>
|
21
|
+
<li>Stay true to the spirit of the languages providing inspiration</li>
|
22
|
+
<li>But implement in a way that makes sense for Ruby</li>
|
23
|
+
<li>Keep the semantics as idiomatic Ruby as possible</li>
|
24
|
+
<li>Support features that make sense in Ruby</li>
|
25
|
+
<li>Exclude features that don't make sense in Ruby</li>
|
26
|
+
<li>Be small, lean, and loosely coupled</li>
|
27
|
+
</ul>
|
28
|
+
</p>
|
29
|
+
</td>
|
30
|
+
<td align="right" valign="top">
|
31
|
+
<img src="https://raw.githubusercontent.com/wiki/jdantonio/concurrent-ruby/logo/concurrent-ruby-logo-300x300.png"/>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
</table>
|
24
35
|
|
25
36
|
## Features & Documentation
|
26
37
|
|
@@ -29,19 +40,21 @@ or the [API documentation](http://rubydoc.info/github/jdantonio/concurrent-ruby/
|
|
29
40
|
for more information or join our [mailing list](http://groups.google.com/group/concurrent-ruby).
|
30
41
|
|
31
42
|
There are many concurrency abstractions in this library. These abstractions can be broadly categorized
|
32
|
-
into several general
|
33
|
-
|
34
|
-
* Asynchronous concurrency abstractions including
|
35
|
-
[
|
36
|
-
[
|
37
|
-
[
|
43
|
+
into several general groups:
|
44
|
+
|
45
|
+
* Asynchronous concurrency abstractions including
|
46
|
+
[Async](https://github.com/jdantonio/concurrent-ruby/wiki/Async),
|
47
|
+
[Agent](https://github.com/jdantonio/concurrent-ruby/wiki/Agent),
|
48
|
+
[Future](https://github.com/jdantonio/concurrent-ruby/wiki/Future),
|
49
|
+
[Promise](https://github.com/jdantonio/concurrent-ruby/wiki/Promise),
|
50
|
+
[ScheduledTask](https://github.com/jdantonio/concurrent-ruby/wiki/ScheduledTask),
|
38
51
|
and [TimerTask](https://github.com/jdantonio/concurrent-ruby/wiki/TimerTask)
|
39
52
|
* Erlang-inspired [Supervisor](https://github.com/jdantonio/concurrent-ruby/wiki/Supervisor) and other lifecycle classes/mixins
|
40
53
|
for managing long-running threads
|
41
54
|
* Thread-safe variables including [M-Structures](https://github.com/jdantonio/concurrent-ruby/wiki/MVar-(M-Structure)),
|
42
55
|
[I-Structures](https://github.com/jdantonio/concurrent-ruby/wiki/IVar-(I-Structure)),
|
43
56
|
[thread-local variables](https://github.com/jdantonio/concurrent-ruby/wiki/ThreadLocalVar),
|
44
|
-
and
|
57
|
+
atomic counters, and [software transactional memory](https://github.com/jdantonio/concurrent-ruby/wiki/TVar-(STM))
|
45
58
|
* Thread synchronization classes and algorithms including [dataflow](https://github.com/jdantonio/concurrent-ruby/wiki/Dataflow),
|
46
59
|
timeout, condition, countdown latch, dependency counter, and event
|
47
60
|
* Java-inspired [thread pools](https://github.com/jdantonio/concurrent-ruby/wiki/Thread%20Pools)
|
@@ -53,73 +66,68 @@ This gem adheres to the rules of [semantic versioning](http://semver.org/).
|
|
53
66
|
|
54
67
|
### Supported Ruby versions
|
55
68
|
|
56
|
-
MRI 1.9.
|
57
|
-
|
69
|
+
MRI 1.9.3, 2.0, 2.1, JRuby (1.9 mode), and Rubinius 2.x.
|
70
|
+
This library is pure Ruby and has no gem dependencies.
|
71
|
+
It should be fully compatible with any interpreter that is compliant with Ruby 1.9.3 or newer.
|
58
72
|
|
59
|
-
###
|
73
|
+
### Examples
|
60
74
|
|
61
75
|
Many more code examples can be found in the documentation for each class (linked above).
|
62
76
|
This one simple example shows some of the power of this gem.
|
63
77
|
|
64
78
|
```ruby
|
65
79
|
require 'concurrent'
|
66
|
-
require '
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
80
|
+
require 'thread' # for Queue
|
81
|
+
require 'open-uri' # for open(uri)
|
82
|
+
|
83
|
+
class Ticker
|
84
|
+
def get_year_end_closing(symbol, year)
|
85
|
+
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
|
86
|
+
data = open(uri) {|f| f.collect{|line| line.strip } }
|
87
|
+
data[1].split(',')[4].to_f
|
71
88
|
end
|
72
89
|
end
|
73
90
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
#=>
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
#=>
|
96
|
-
|
97
|
-
#=>
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
91
|
+
# Future
|
92
|
+
price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
|
93
|
+
price.state #=> :pending
|
94
|
+
sleep(1) # do other stuff
|
95
|
+
price.value #=> 63.65
|
96
|
+
price.state #=> :fulfilled
|
97
|
+
|
98
|
+
# Promise
|
99
|
+
prices = Concurrent::Promise.new{ puts Ticker.new.get_year_end_closing('AAPL', 2013) }.
|
100
|
+
then{ puts Ticker.new.get_year_end_closing('MSFT', 2013) }.
|
101
|
+
then{ puts Ticker.new.get_year_end_closing('GOOG', 2013) }.
|
102
|
+
then{ puts Ticker.new.get_year_end_closing('AMZN', 2013) }.execute
|
103
|
+
prices.state #=> :pending
|
104
|
+
sleep(1) # do other stuff
|
105
|
+
#=> 561.02
|
106
|
+
#=> 37.41
|
107
|
+
#=> 1120.71
|
108
|
+
#=> 398.79
|
109
|
+
|
110
|
+
# ScheduledTask
|
111
|
+
task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
|
112
|
+
task.state #=> :pending
|
113
|
+
sleep(3) # do other stuff
|
114
|
+
task.value #=> 25.96
|
115
|
+
|
116
|
+
# Async
|
117
|
+
ticker = Ticker.new
|
118
|
+
ticker.extend(Concurrent::Async)
|
119
|
+
hpq = ticker.async.get_year_end_closing('HPQ', 2013)
|
120
|
+
ibm = ticker.await.get_year_end_closing('IBM', 2013)
|
121
|
+
hpq.value #=> 27.98
|
122
|
+
ibm.value #=> 187.57
|
103
123
|
```
|
104
124
|
|
105
|
-
### Disclaimer
|
106
|
-
|
107
|
-
Remember, *there is no silver bullet in concurrent programming.* Concurrency is hard.
|
108
|
-
These tools will help ease the burden, but at the end of the day it is essential that you
|
109
|
-
*know what you are doing.*
|
110
|
-
|
111
|
-
* Decouple business logic from concurrency logic
|
112
|
-
* Test business logic separate from concurrency logic
|
113
|
-
* Keep the intersection of business logic and concurrency and small as possible
|
114
|
-
* Don't share mutable data unless absolutely necessary
|
115
|
-
* Protect shared data as much as possible (prefer [immutability](https://github.com/harukizaemon/hamster))
|
116
|
-
* Don't mix Ruby's [concurrency](http://ruby-doc.org/core-2.0.0/Thread.html)
|
117
|
-
[primitives](http://www.ruby-doc.org/core-2.0.0/Mutex.html) with asynchronous concurrency libraries
|
118
|
-
|
119
125
|
## Contributors
|
120
126
|
|
127
|
+
* [Jerry D'Antonio](https://github.com/jdantonio)
|
121
128
|
* [Michele Della Torre](https://github.com/mighe)
|
122
129
|
* [Chris Seaton](https://github.com/chrisseaton)
|
130
|
+
* [Lucas Allan](https://github.com/lucasallan)
|
123
131
|
* [Giuseppe Capizzi](https://github.com/gcapizzi)
|
124
132
|
* [Brian Shirai](https://github.com/brixen)
|
125
133
|
* [Chip Miller](https://github.com/chip-miller)
|
@@ -136,5 +144,8 @@ These tools will help ease the burden, but at the end of the day it is essential
|
|
136
144
|
|
137
145
|
## License and Copyright
|
138
146
|
|
139
|
-
*Concurrent Ruby* is
|
140
|
-
|
147
|
+
*Concurrent Ruby* is free software released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
148
|
+
|
149
|
+
The *Concurrent Ruby* [logo](https://github.com/jdantonio/concurrent-ruby/wiki/Logo)
|
150
|
+
was designed by [David Jones](https://twitter.com/zombyboy).
|
151
|
+
It is Copyright © 2014 [Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved.
|
data/lib/concurrent.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'concurrent/version'
|
2
|
+
require 'concurrent/configuration'
|
2
3
|
|
3
4
|
require 'concurrent/atomic'
|
4
5
|
require 'concurrent/count_down_latch'
|
@@ -10,14 +11,17 @@ require 'concurrent/ivar'
|
|
10
11
|
|
11
12
|
require 'concurrent/actor'
|
12
13
|
require 'concurrent/agent'
|
13
|
-
require 'concurrent/
|
14
|
+
require 'concurrent/async'
|
14
15
|
require 'concurrent/dataflow'
|
16
|
+
require 'concurrent/delay'
|
15
17
|
require 'concurrent/dereferenceable'
|
16
18
|
require 'concurrent/event'
|
19
|
+
require 'concurrent/exchanger'
|
17
20
|
require 'concurrent/future'
|
18
21
|
require 'concurrent/mvar'
|
19
22
|
require 'concurrent/obligation'
|
20
23
|
require 'concurrent/postable'
|
24
|
+
require 'concurrent/processor_count'
|
21
25
|
require 'concurrent/promise'
|
22
26
|
require 'concurrent/runnable'
|
23
27
|
require 'concurrent/scheduled_task'
|
@@ -25,13 +29,24 @@ require 'concurrent/stoppable'
|
|
25
29
|
require 'concurrent/supervisor'
|
26
30
|
require 'concurrent/thread_local_var'
|
27
31
|
require 'concurrent/timer_task'
|
32
|
+
require 'concurrent/tvar'
|
28
33
|
require 'concurrent/utilities'
|
29
34
|
|
30
|
-
require 'concurrent/
|
35
|
+
require 'concurrent/channel/probe'
|
36
|
+
require 'concurrent/channel/channel'
|
37
|
+
require 'concurrent/channel/unbuffered_channel'
|
38
|
+
require 'concurrent/channel/buffered_channel'
|
39
|
+
require 'concurrent/channel/ring_buffer'
|
40
|
+
require 'concurrent/channel/blocking_ring_buffer'
|
41
|
+
|
42
|
+
require 'concurrent/actor_context'
|
43
|
+
require 'concurrent/simple_actor_ref'
|
31
44
|
|
32
45
|
require 'concurrent/cached_thread_pool'
|
33
46
|
require 'concurrent/fixed_thread_pool'
|
34
47
|
require 'concurrent/immediate_executor'
|
48
|
+
require 'concurrent/per_thread_executor'
|
49
|
+
require 'concurrent/thread_pool_executor'
|
35
50
|
|
36
51
|
# Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell,
|
37
52
|
# F#, C#, Java, and classic concurrency patterns.
|
data/lib/concurrent/actor.rb
CHANGED
@@ -119,6 +119,8 @@ module Concurrent
|
|
119
119
|
#
|
120
120
|
# ping << :pong
|
121
121
|
#
|
122
|
+
# @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
|
123
|
+
#
|
122
124
|
# @see http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html
|
123
125
|
class Actor
|
124
126
|
include Observable
|
@@ -174,7 +176,10 @@ module Concurrent
|
|
174
176
|
# #=> [6] handled by #<EchoActor:0x007fc8014fb8b8>
|
175
177
|
# #=> [7] handled by #<EchoActor:0x007fc8014fb818>
|
176
178
|
# #=> [8] handled by #<EchoActor:0x007fc8014fb890>
|
179
|
+
#
|
180
|
+
# @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
|
177
181
|
def self.pool(count, *args, &block)
|
182
|
+
warn '[DEPRECATED] `Actor` is deprecated and will be replaced with `ActorContext`.'
|
178
183
|
raise ArgumentError.new('count must be greater than zero') unless count > 0
|
179
184
|
mailbox = Queue.new
|
180
185
|
actors = count.times.collect do
|
@@ -202,24 +207,34 @@ module Concurrent
|
|
202
207
|
# @return [Object] the result obtained when the message is successfully processed
|
203
208
|
#
|
204
209
|
# @raise NotImplementedError unless overridden in the +Actor+ subclass
|
210
|
+
#
|
211
|
+
# @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
|
205
212
|
#
|
206
213
|
# @!visibility public
|
207
214
|
def act(*message)
|
215
|
+
warn '[DEPRECATED] `Actor` is deprecated and will be replaced with `ActorContext`.'
|
208
216
|
raise NotImplementedError.new("#{self.class} does not implement #act")
|
209
217
|
end
|
210
218
|
|
211
219
|
# @!visibility private
|
220
|
+
#
|
221
|
+
# @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
|
212
222
|
def on_run # :nodoc:
|
223
|
+
warn '[DEPRECATED] `Actor` is deprecated and will be replaced with `ActorContext`.'
|
213
224
|
queue.clear
|
214
225
|
end
|
215
226
|
|
216
227
|
# @!visibility private
|
228
|
+
#
|
229
|
+
# @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
|
217
230
|
def on_stop # :nodoc:
|
218
231
|
queue.clear
|
219
232
|
queue.push(:stop)
|
220
233
|
end
|
221
234
|
|
222
235
|
# @!visibility private
|
236
|
+
#
|
237
|
+
# @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
|
223
238
|
def on_task # :nodoc:
|
224
239
|
package = queue.pop
|
225
240
|
return if package == :stop
|
@@ -247,6 +262,8 @@ module Concurrent
|
|
247
262
|
end
|
248
263
|
|
249
264
|
# @!visibility private
|
265
|
+
#
|
266
|
+
# @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
|
250
267
|
def on_error(time, msg, ex) # :nodoc:
|
251
268
|
end
|
252
269
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'concurrent/simple_actor_ref'
|
2
|
+
|
3
|
+
module Concurrent
|
4
|
+
|
5
|
+
module ActorContext
|
6
|
+
|
7
|
+
def on_start
|
8
|
+
end
|
9
|
+
|
10
|
+
def on_reset
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_shutdown
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_error(time, message, exception)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.included(base)
|
20
|
+
|
21
|
+
class << base
|
22
|
+
protected :new
|
23
|
+
|
24
|
+
def spawn(opts = {})
|
25
|
+
args = opts.fetch(:args, [])
|
26
|
+
Concurrent::SimpleActorRef.new(self.new(*args), opts)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'concurrent/copy_on_notify_observer_set'
|
2
|
+
|
3
|
+
module Concurrent
|
4
|
+
|
5
|
+
module ActorRef
|
6
|
+
|
7
|
+
#NOTE: Required API methods
|
8
|
+
# Must be implemented in all subclasses
|
9
|
+
#def post(*msg, &block)
|
10
|
+
#def post!(*msg)
|
11
|
+
#def running?
|
12
|
+
#def shutdown?
|
13
|
+
#def shutdown
|
14
|
+
#def join(timeout = nil)
|
15
|
+
|
16
|
+
def <<(message)
|
17
|
+
post(*message)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_observer(*args)
|
22
|
+
@observers.add_observer(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete_observer(*args)
|
26
|
+
@observers.delete_observer(*args)
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete_observers
|
30
|
+
@observers.delete_observers
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def observers
|
36
|
+
@observers ||= CopyOnNotifyObserverSet.new
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/concurrent/agent.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'observer'
|
3
3
|
|
4
|
+
require 'concurrent/configuration'
|
4
5
|
require 'concurrent/dereferenceable'
|
5
|
-
require 'concurrent/global_thread_pool'
|
6
6
|
require 'concurrent/utilities'
|
7
7
|
|
8
8
|
module Concurrent
|
@@ -34,7 +34,7 @@ module Concurrent
|
|
34
34
|
# @return [Fixnum] the maximum number of seconds before an update is cancelled
|
35
35
|
class Agent
|
36
36
|
include Dereferenceable
|
37
|
-
include
|
37
|
+
include OptionsParser
|
38
38
|
|
39
39
|
# The default timeout value (in seconds); used when no timeout option
|
40
40
|
# is given at initialization
|
@@ -46,7 +46,15 @@ module Concurrent
|
|
46
46
|
#
|
47
47
|
# @param [Object] initial the initial value
|
48
48
|
# @param [Hash] opts the options used to define the behavior at update and deref
|
49
|
+
#
|
49
50
|
# @option opts [Fixnum] :timeout (TIMEOUT) maximum number of seconds before an update is cancelled
|
51
|
+
#
|
52
|
+
# @option opts [Boolean] :operation (false) when +true+ will execute the future on the global
|
53
|
+
# operation pool (for long-running operations), when +false+ will execute the future on the
|
54
|
+
# global task pool (for short-running tasks)
|
55
|
+
# @option opts [object] :executor when provided will run all operations on
|
56
|
+
# this executor rather than the global thread pool (overrides :operation)
|
57
|
+
#
|
50
58
|
# @option opts [String] :dup_on_deref (false) call +#dup+ before returning the data
|
51
59
|
# @option opts [String] :freeze_on_deref (false) call +#freeze+ before returning the data
|
52
60
|
# @option opts [String] :copy_on_deref (nil) call the given +Proc+ passing the internal value and
|
@@ -57,6 +65,7 @@ module Concurrent
|
|
57
65
|
@validator = Proc.new { |result| true }
|
58
66
|
@timeout = opts.fetch(:timeout, TIMEOUT).freeze
|
59
67
|
@observers = CopyOnWriteObserverSet.new
|
68
|
+
@executor = get_executor_from(opts)
|
60
69
|
init_mutex
|
61
70
|
set_deref_options(opts)
|
62
71
|
end
|
@@ -116,7 +125,7 @@ module Concurrent
|
|
116
125
|
# @yieldparam [Object] value the current value
|
117
126
|
# @yieldreturn [Object] the new value
|
118
127
|
def post(&block)
|
119
|
-
|
128
|
+
@executor.post{ work(&block) } unless block.nil?
|
120
129
|
end
|
121
130
|
|
122
131
|
# Update the current value with the result of the given block operation
|