concurrent-ruby 0.5.0 → 0.6.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.png)](http://badge.fury.io/rb/concurrent-ruby) [![Build Status](https://secure.travis-ci.org/jdantonio/concurrent-ruby.png)](https://travis-ci.org/jdantonio/concurrent-ruby?branch=master) [![Coverage Status](https://coveralls.io/repos/jdantonio/concurrent-ruby/badge.png)](https://coveralls.io/r/jdantonio/concurrent-ruby) [![Code Climate](https://codeclimate.com/github/jdantonio/concurrent-ruby.png)](https://codeclimate.com/github/jdantonio/concurrent-ruby) [![Inline docs](http://inch-pages.github.io/github/jdantonio/concurrent-ruby.png)](http://inch-pages.github.io/github/jdantonio/concurrent-ruby) [![Dependency Status](https://gemnasium.com/jdantonio/concurrent-ruby.png)](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
|