concurrent-ruby 0.7.0-java
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.
- data/LICENSE.txt +21 -0
- data/README.md +217 -0
- data/lib/concurrent.rb +45 -0
- data/lib/concurrent/actor.rb +104 -0
- data/lib/concurrent/actor/behaviour.rb +70 -0
- data/lib/concurrent/actor/behaviour/abstract.rb +48 -0
- data/lib/concurrent/actor/behaviour/awaits.rb +21 -0
- data/lib/concurrent/actor/behaviour/buffer.rb +54 -0
- data/lib/concurrent/actor/behaviour/errors_on_unknown_message.rb +12 -0
- data/lib/concurrent/actor/behaviour/executes_context.rb +18 -0
- data/lib/concurrent/actor/behaviour/linking.rb +42 -0
- data/lib/concurrent/actor/behaviour/pausing.rb +77 -0
- data/lib/concurrent/actor/behaviour/removes_child.rb +16 -0
- data/lib/concurrent/actor/behaviour/sets_results.rb +36 -0
- data/lib/concurrent/actor/behaviour/supervised.rb +58 -0
- data/lib/concurrent/actor/behaviour/supervising.rb +34 -0
- data/lib/concurrent/actor/behaviour/terminates_children.rb +13 -0
- data/lib/concurrent/actor/behaviour/termination.rb +54 -0
- data/lib/concurrent/actor/context.rb +153 -0
- data/lib/concurrent/actor/core.rb +213 -0
- data/lib/concurrent/actor/default_dead_letter_handler.rb +9 -0
- data/lib/concurrent/actor/envelope.rb +41 -0
- data/lib/concurrent/actor/errors.rb +27 -0
- data/lib/concurrent/actor/internal_delegations.rb +49 -0
- data/lib/concurrent/actor/public_delegations.rb +40 -0
- data/lib/concurrent/actor/reference.rb +81 -0
- data/lib/concurrent/actor/root.rb +37 -0
- data/lib/concurrent/actor/type_check.rb +48 -0
- data/lib/concurrent/actor/utils.rb +10 -0
- data/lib/concurrent/actor/utils/ad_hoc.rb +21 -0
- data/lib/concurrent/actor/utils/balancer.rb +40 -0
- data/lib/concurrent/actor/utils/broadcast.rb +52 -0
- data/lib/concurrent/actor/utils/pool.rb +59 -0
- data/lib/concurrent/actress.rb +3 -0
- data/lib/concurrent/agent.rb +230 -0
- data/lib/concurrent/async.rb +284 -0
- data/lib/concurrent/atomic.rb +91 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +202 -0
- data/lib/concurrent/atomic/atomic_fixnum.rb +203 -0
- data/lib/concurrent/atomic/condition.rb +67 -0
- data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +118 -0
- data/lib/concurrent/atomic/copy_on_write_observer_set.rb +117 -0
- data/lib/concurrent/atomic/count_down_latch.rb +116 -0
- data/lib/concurrent/atomic/cyclic_barrier.rb +106 -0
- data/lib/concurrent/atomic/event.rb +98 -0
- data/lib/concurrent/atomic/synchronization.rb +51 -0
- data/lib/concurrent/atomic/thread_local_var.rb +82 -0
- data/lib/concurrent/atomic_reference/concurrent_update_error.rb +8 -0
- data/lib/concurrent/atomic_reference/direct_update.rb +50 -0
- data/lib/concurrent/atomic_reference/jruby.rb +14 -0
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +77 -0
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +25 -0
- data/lib/concurrent/atomic_reference/rbx.rb +19 -0
- data/lib/concurrent/atomic_reference/ruby.rb +37 -0
- data/lib/concurrent/atomics.rb +11 -0
- data/lib/concurrent/channel/buffered_channel.rb +85 -0
- data/lib/concurrent/channel/channel.rb +41 -0
- data/lib/concurrent/channel/unbuffered_channel.rb +35 -0
- data/lib/concurrent/channel/waitable_list.rb +40 -0
- data/lib/concurrent/channels.rb +5 -0
- data/lib/concurrent/collection/blocking_ring_buffer.rb +71 -0
- data/lib/concurrent/collection/priority_queue.rb +305 -0
- data/lib/concurrent/collection/ring_buffer.rb +59 -0
- data/lib/concurrent/collections.rb +3 -0
- data/lib/concurrent/configuration.rb +161 -0
- data/lib/concurrent/dataflow.rb +108 -0
- data/lib/concurrent/delay.rb +104 -0
- data/lib/concurrent/dereferenceable.rb +101 -0
- data/lib/concurrent/errors.rb +30 -0
- data/lib/concurrent/exchanger.rb +34 -0
- data/lib/concurrent/executor/cached_thread_pool.rb +44 -0
- data/lib/concurrent/executor/executor.rb +282 -0
- data/lib/concurrent/executor/fixed_thread_pool.rb +33 -0
- data/lib/concurrent/executor/immediate_executor.rb +65 -0
- data/lib/concurrent/executor/java_cached_thread_pool.rb +31 -0
- data/lib/concurrent/executor/java_fixed_thread_pool.rb +41 -0
- data/lib/concurrent/executor/java_single_thread_executor.rb +22 -0
- data/lib/concurrent/executor/java_thread_pool_executor.rb +180 -0
- data/lib/concurrent/executor/per_thread_executor.rb +100 -0
- data/lib/concurrent/executor/ruby_cached_thread_pool.rb +29 -0
- data/lib/concurrent/executor/ruby_fixed_thread_pool.rb +32 -0
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +74 -0
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +288 -0
- data/lib/concurrent/executor/ruby_thread_pool_worker.rb +72 -0
- data/lib/concurrent/executor/safe_task_executor.rb +35 -0
- data/lib/concurrent/executor/serialized_execution.rb +126 -0
- data/lib/concurrent/executor/single_thread_executor.rb +35 -0
- data/lib/concurrent/executor/thread_pool_executor.rb +68 -0
- data/lib/concurrent/executor/timer_set.rb +143 -0
- data/lib/concurrent/executors.rb +9 -0
- data/lib/concurrent/future.rb +125 -0
- data/lib/concurrent/ivar.rb +111 -0
- data/lib/concurrent/lazy_register.rb +58 -0
- data/lib/concurrent/logging.rb +17 -0
- data/lib/concurrent/mvar.rb +200 -0
- data/lib/concurrent/obligation.rb +171 -0
- data/lib/concurrent/observable.rb +40 -0
- data/lib/concurrent/options_parser.rb +48 -0
- data/lib/concurrent/promise.rb +170 -0
- data/lib/concurrent/scheduled_task.rb +79 -0
- data/lib/concurrent/timer_task.rb +341 -0
- data/lib/concurrent/tvar.rb +248 -0
- data/lib/concurrent/utilities.rb +3 -0
- data/lib/concurrent/utility/processor_count.rb +152 -0
- data/lib/concurrent/utility/timeout.rb +35 -0
- data/lib/concurrent/utility/timer.rb +21 -0
- data/lib/concurrent/version.rb +3 -0
- data/lib/concurrent_ruby.rb +1 -0
- data/lib/concurrent_ruby_ext.jar +0 -0
- data/lib/concurrent_ruby_ext.so +0 -0
- data/lib/extension_helper.rb +28 -0
- metadata +163 -0
data/LICENSE.txt
ADDED
@@ -0,0 +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.
|
data/README.md
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
# Concurrent Ruby
|
2
|
+
[](http://badge.fury.io/rb/concurrent-ruby) [](https://travis-ci.org/ruby-concurrency/concurrent-ruby) [](https://coveralls.io/r/ruby-concurrency/concurrent-ruby) [](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby) [](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby) [](https://gemnasium.com/ruby-concurrency/concurrent-ruby) [](http://opensource.org/licenses/MIT) [](https://gitter.im/ruby-concurrency/concurrent-ruby)
|
3
|
+
|
4
|
+
<table>
|
5
|
+
<tr>
|
6
|
+
<td align="left" valign="top">
|
7
|
+
<p>
|
8
|
+
Modern concurrency tools for Ruby. Inspired by
|
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://akka.io/">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>,
|
16
|
+
and classic concurrency patterns.
|
17
|
+
</p>
|
18
|
+
<p>
|
19
|
+
The design goals of this gem are:
|
20
|
+
<ul>
|
21
|
+
<li>Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why</li>
|
22
|
+
<li>Remain free of external gem dependencies</li>
|
23
|
+
<li>Stay true to the spirit of the languages providing inspiration</li>
|
24
|
+
<li>But implement in a way that makes sense for Ruby</li>
|
25
|
+
<li>Keep the semantics as idiomatic Ruby as possible</li>
|
26
|
+
<li>Support features that make sense in Ruby</li>
|
27
|
+
<li>Exclude features that don't make sense in Ruby</li>
|
28
|
+
<li>Be small, lean, and loosely coupled</li>
|
29
|
+
</ul>
|
30
|
+
</p>
|
31
|
+
</td>
|
32
|
+
<td align="right" valign="top">
|
33
|
+
<img src="https://raw.githubusercontent.com/wiki/ruby-concurrency/concurrent-ruby/logo/concurrent-ruby-logo-300x300.png"/>
|
34
|
+
</td>
|
35
|
+
</tr>
|
36
|
+
</table>
|
37
|
+
|
38
|
+
## Features & Documentation
|
39
|
+
|
40
|
+
Please see the [Concurrent Ruby Wiki](https://github.com/ruby-concurrency/concurrent-ruby/wiki)
|
41
|
+
or the [API documentation](http://ruby-concurrency.github.io/concurrent-ruby/frames.html)
|
42
|
+
for more information or join our [mailing list](http://groups.google.com/group/concurrent-ruby).
|
43
|
+
|
44
|
+
There are many concurrency abstractions in this library. These abstractions can be broadly categorized
|
45
|
+
into several general groups:
|
46
|
+
|
47
|
+
* Asynchronous concurrency abstractions including
|
48
|
+
[Agent](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Agent.html),
|
49
|
+
[Async](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Async.html),
|
50
|
+
[Future](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Future.html),
|
51
|
+
[Promise](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promise.html),
|
52
|
+
[ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ScheduledTask.html),
|
53
|
+
and [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html)
|
54
|
+
* Fast, light-weight [Actor model](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html) implementation.
|
55
|
+
* Thread-safe variables including
|
56
|
+
[I-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html),
|
57
|
+
[M-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html),
|
58
|
+
[thread-local variables](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html),
|
59
|
+
and [software transactional memory](https://github.com/ruby-concurrency/concurrent-ruby/wiki/TVar-(STM))
|
60
|
+
* Thread synchronization classes and algorithms including
|
61
|
+
[condition](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Condition.html),
|
62
|
+
[countdown latch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html),
|
63
|
+
[dataflow](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Dataflow),
|
64
|
+
[event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html),
|
65
|
+
[exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html),
|
66
|
+
and [timeout](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#timeout-class_method)
|
67
|
+
* Java-inspired [executors](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Thread%20Pools) (thread pools and more)
|
68
|
+
* [And many more](http://ruby-concurrency.github.io/concurrent-ruby/index.html)...
|
69
|
+
|
70
|
+
### Semantic Versioning
|
71
|
+
|
72
|
+
This gem adheres to the rules of [semantic versioning](http://semver.org/).
|
73
|
+
|
74
|
+
### Supported Ruby versions
|
75
|
+
|
76
|
+
MRI 1.9.3, 2.0, 2.1, JRuby (1.9 mode), and Rubinius 2.x.
|
77
|
+
This library is pure Ruby and has no gem dependencies.
|
78
|
+
It should be fully compatible with any interpreter that is compliant with Ruby 1.9.3 or newer.
|
79
|
+
|
80
|
+
### Examples
|
81
|
+
|
82
|
+
Many more code examples can be found in the documentation for each class (linked above).
|
83
|
+
|
84
|
+
Future and ScheduledTask:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
require 'concurrent'
|
88
|
+
require 'thread' # for Queue
|
89
|
+
require 'open-uri' # for open(uri)
|
90
|
+
|
91
|
+
class Ticker
|
92
|
+
def get_year_end_closing(symbol, year)
|
93
|
+
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
|
94
|
+
data = open(uri) {|f| f.collect{|line| line.strip } }
|
95
|
+
data[1].split(',')[4].to_f
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Future
|
100
|
+
price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
|
101
|
+
price.state #=> :pending
|
102
|
+
sleep(1) # do other stuff
|
103
|
+
price.value #=> 63.65
|
104
|
+
price.state #=> :fulfilled
|
105
|
+
|
106
|
+
# ScheduledTask
|
107
|
+
task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
|
108
|
+
task.state #=> :pending
|
109
|
+
sleep(3) # do other stuff
|
110
|
+
task.value #=> 25.96
|
111
|
+
```
|
112
|
+
|
113
|
+
Actor:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
class Counter < Concurrent::Actor::Context
|
117
|
+
# Include context of an actor which gives this class access to reference
|
118
|
+
# and other information about the actor
|
119
|
+
|
120
|
+
# use initialize as you wish
|
121
|
+
def initialize(initial_value)
|
122
|
+
@count = initial_value
|
123
|
+
end
|
124
|
+
|
125
|
+
# override on_message to define actor's behaviour
|
126
|
+
def on_message(message)
|
127
|
+
if Integer === message
|
128
|
+
@count += message
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end #
|
132
|
+
|
133
|
+
# Create new actor naming the instance 'first'.
|
134
|
+
# Return value is a reference to the actor, the actual actor is never returned.
|
135
|
+
counter = Counter.spawn(:first, 5)
|
136
|
+
|
137
|
+
# Tell a message and forget returning self.
|
138
|
+
counter.tell(1)
|
139
|
+
counter << 1
|
140
|
+
# (First counter now contains 7.)
|
141
|
+
|
142
|
+
# Send a messages asking for a result.
|
143
|
+
counter.ask(0).class
|
144
|
+
counter.ask(0).value
|
145
|
+
```
|
146
|
+
|
147
|
+
## Installing and Building
|
148
|
+
|
149
|
+
This gem includes several platform-specific optimizations. To reduce the possibility of
|
150
|
+
compilation errors, we provide pre-compiled gem packages for several platforms as well
|
151
|
+
as a pure-Ruby build. Installing the gem should be no different than installing any other
|
152
|
+
Rubygems-hosted gem.
|
153
|
+
|
154
|
+
### Installing
|
155
|
+
|
156
|
+
```shell
|
157
|
+
gem install concurrent-ruby
|
158
|
+
```
|
159
|
+
|
160
|
+
or add the following line to Gemfile:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
gem 'concurrent-ruby'
|
164
|
+
```
|
165
|
+
|
166
|
+
and run `bundle install` from your shell.
|
167
|
+
|
168
|
+
### Building
|
169
|
+
|
170
|
+
Because we provide pre-compiled gem builds, users should never need to build the gem manually.
|
171
|
+
The build process for this gem is completely automated using open source tools. All of
|
172
|
+
the automation components are available in the [ruby-concurrency/rake-compiler-dev-box](https://github.com/ruby-concurrency/rake-compiler-dev-box)
|
173
|
+
GitHub repository.
|
174
|
+
|
175
|
+
This gem will compile native C code under MRI and native Java code under JRuby. It is
|
176
|
+
also possible to build a pure-Ruby version. All builds have identical functionality.
|
177
|
+
The only difference is performance. Additionally, pure-Ruby classes are always available,
|
178
|
+
even when using the native optimizations. Please see the [documentation](http://ruby-concurrency.github.io/concurrent-ruby/)
|
179
|
+
for more details.
|
180
|
+
|
181
|
+
To build and package the gem using MRI or JRuby, install the necessary build dependencies and run:
|
182
|
+
|
183
|
+
```shell
|
184
|
+
bundle exec rake compile
|
185
|
+
bundle exec rake build
|
186
|
+
```
|
187
|
+
|
188
|
+
To build and package a pure-Ruby gem, on *any* platform and interpreter
|
189
|
+
(including MRI and JRuby), run:
|
190
|
+
|
191
|
+
```shell
|
192
|
+
BUILD_PURE_RUBY='true' bundle exec rake build
|
193
|
+
```
|
194
|
+
|
195
|
+
## Maintainers
|
196
|
+
|
197
|
+
* [Jerry D'Antonio](https://github.com/jdantonio)
|
198
|
+
* [Michele Della Torre](https://github.com/mighe)
|
199
|
+
* [Chris Seaton](https://github.com/chrisseaton)
|
200
|
+
* [Lucas Allan](https://github.com/lucasallan)
|
201
|
+
* [Petr Chalupa](https://github.com/pitr-ch)
|
202
|
+
|
203
|
+
### Contributing
|
204
|
+
|
205
|
+
1. Fork it
|
206
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
207
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
208
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
209
|
+
5. Create new Pull Request
|
210
|
+
|
211
|
+
## License and Copyright
|
212
|
+
|
213
|
+
*Concurrent Ruby* is free software released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
214
|
+
|
215
|
+
The *Concurrent Ruby* [logo](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Logo)
|
216
|
+
was designed by [David Jones](https://twitter.com/zombyboy).
|
217
|
+
It is Copyright © 2014 [Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved.
|
data/lib/concurrent.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'concurrent/version'
|
2
|
+
|
3
|
+
require 'concurrent/configuration'
|
4
|
+
|
5
|
+
require 'concurrent/atomics'
|
6
|
+
require 'concurrent/channels'
|
7
|
+
require 'concurrent/collections'
|
8
|
+
require 'concurrent/executors'
|
9
|
+
require 'concurrent/utilities'
|
10
|
+
|
11
|
+
require 'concurrent/actor'
|
12
|
+
require 'concurrent/atomic'
|
13
|
+
require 'concurrent/lazy_register'
|
14
|
+
require 'concurrent/agent'
|
15
|
+
require 'concurrent/async'
|
16
|
+
require 'concurrent/dataflow'
|
17
|
+
require 'concurrent/delay'
|
18
|
+
require 'concurrent/dereferenceable'
|
19
|
+
require 'concurrent/errors'
|
20
|
+
require 'concurrent/exchanger'
|
21
|
+
require 'concurrent/future'
|
22
|
+
require 'concurrent/ivar'
|
23
|
+
require 'concurrent/mvar'
|
24
|
+
require 'concurrent/obligation'
|
25
|
+
require 'concurrent/observable'
|
26
|
+
require 'concurrent/options_parser'
|
27
|
+
require 'concurrent/promise'
|
28
|
+
require 'concurrent/scheduled_task'
|
29
|
+
require 'concurrent/timer_task'
|
30
|
+
require 'concurrent/tvar'
|
31
|
+
|
32
|
+
# Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell,
|
33
|
+
# F#, C#, Java, and classic concurrency patterns.
|
34
|
+
#
|
35
|
+
# The design goals of this gem are:
|
36
|
+
#
|
37
|
+
# * Stay true to the spirit of the languages providing inspiration
|
38
|
+
# * But implement in a way that makes sense for Ruby
|
39
|
+
# * Keep the semantics as idiomatic Ruby as possible
|
40
|
+
# * Support features that make sense in Ruby
|
41
|
+
# * Exclude features that don't make sense in Ruby
|
42
|
+
# * Be small, lean, and loosely coupled
|
43
|
+
module Concurrent
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'concurrent/configuration'
|
2
|
+
require 'concurrent/executor/serialized_execution'
|
3
|
+
require 'concurrent/ivar'
|
4
|
+
require 'concurrent/logging'
|
5
|
+
require 'concurrent/atomic/synchronization'
|
6
|
+
|
7
|
+
module Concurrent
|
8
|
+
# TODO https://github.com/celluloid/celluloid/wiki/Supervision-Groups
|
9
|
+
|
10
|
+
# TODO doc
|
11
|
+
# - what happens if I try to supervise using a normal Context?
|
12
|
+
|
13
|
+
|
14
|
+
# {include:file:doc/actor/main.md}
|
15
|
+
module Actor
|
16
|
+
|
17
|
+
require 'concurrent/actor/type_check'
|
18
|
+
require 'concurrent/actor/errors'
|
19
|
+
require 'concurrent/actor/public_delegations'
|
20
|
+
require 'concurrent/actor/internal_delegations'
|
21
|
+
require 'concurrent/actor/envelope'
|
22
|
+
require 'concurrent/actor/reference'
|
23
|
+
require 'concurrent/actor/core'
|
24
|
+
require 'concurrent/actor/behaviour'
|
25
|
+
require 'concurrent/actor/context'
|
26
|
+
|
27
|
+
require 'concurrent/actor/default_dead_letter_handler'
|
28
|
+
require 'concurrent/actor/root'
|
29
|
+
require 'concurrent/actor/utils'
|
30
|
+
|
31
|
+
# @return [Reference, nil] current executing actor if any
|
32
|
+
def self.current
|
33
|
+
Thread.current[:__current_actor__]
|
34
|
+
end
|
35
|
+
|
36
|
+
@root = Delay.new do
|
37
|
+
Core.new(parent: nil, name: '/', class: Root, initialized: ivar = IVar.new).reference.tap do
|
38
|
+
ivar.no_error!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# A root actor, a default parent of all actors spawned outside an actor
|
43
|
+
def self.root
|
44
|
+
@root.value!
|
45
|
+
end
|
46
|
+
|
47
|
+
# Spawns a new actor.
|
48
|
+
#
|
49
|
+
# @example simple
|
50
|
+
# Actor.spawn(AdHoc, :ping1) { -> message { message } }
|
51
|
+
#
|
52
|
+
# @example complex
|
53
|
+
# Actor.spawn name: :ping3,
|
54
|
+
# class: AdHoc,
|
55
|
+
# args: [1]
|
56
|
+
# executor: Concurrent.configuration.global_task_pool do |add|
|
57
|
+
# lambda { |number| number + add }
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# @param block for context_class instantiation
|
61
|
+
# @param args see {.spawn_optionify}
|
62
|
+
# @return [Reference] never the actual actor
|
63
|
+
def self.spawn(*args, &block)
|
64
|
+
experimental_acknowledged? or
|
65
|
+
warn '[EXPERIMENTAL] A full release of `Actor`, is expected in the 0.7.0 release.'
|
66
|
+
|
67
|
+
if Actor.current
|
68
|
+
Core.new(spawn_optionify(*args).merge(parent: Actor.current), &block).reference
|
69
|
+
else
|
70
|
+
root.ask([:spawn, spawn_optionify(*args), block]).value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# as {.spawn} but it'll raise when Actor not initialized properly
|
75
|
+
def self.spawn!(*args, &block)
|
76
|
+
spawn(spawn_optionify(*args).merge(initialized: ivar = IVar.new), &block).tap { ivar.no_error! }
|
77
|
+
end
|
78
|
+
|
79
|
+
# @overload spawn_optionify(context_class, name, *args)
|
80
|
+
# @param [Context] context_class to be spawned
|
81
|
+
# @param [String, Symbol] name of the instance, it's used to generate the {Core#path} of the actor
|
82
|
+
# @param args for context_class instantiation
|
83
|
+
# @overload spawn_optionify(opts)
|
84
|
+
# see {Core#initialize} opts
|
85
|
+
def self.spawn_optionify(*args)
|
86
|
+
if args.size == 1 && args.first.is_a?(Hash)
|
87
|
+
args.first
|
88
|
+
else
|
89
|
+
{ class: args[0],
|
90
|
+
name: args[1],
|
91
|
+
args: args[2..-1] }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# call this to disable experimental warning
|
96
|
+
def self.i_know_it_is_experimental!
|
97
|
+
@experimental_acknowledged = true
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.experimental_acknowledged?
|
101
|
+
!!@experimental_acknowledged
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Actor
|
3
|
+
|
4
|
+
# Actors have modular architecture, which is achieved by combining a light core with chain of
|
5
|
+
# behaviours. Each message or internal event propagates through the chain allowing the
|
6
|
+
# behaviours react based on their responsibility. listing few as an example:
|
7
|
+
#
|
8
|
+
# - {Behaviour::Linking}:
|
9
|
+
#
|
10
|
+
# > {include:Actor::Behaviour::Linking}
|
11
|
+
#
|
12
|
+
# - {Behaviour::Awaits}:
|
13
|
+
#
|
14
|
+
# > {include:Actor::Behaviour::Awaits}
|
15
|
+
#
|
16
|
+
# See {Behaviour}'s namespace fo other behaviours.
|
17
|
+
# If needed new behaviours can be added, or old one removed to get required behaviour.
|
18
|
+
module Behaviour
|
19
|
+
MESSAGE_PROCESSED = Object.new
|
20
|
+
|
21
|
+
require 'concurrent/actor/behaviour/abstract'
|
22
|
+
require 'concurrent/actor/behaviour/awaits'
|
23
|
+
require 'concurrent/actor/behaviour/buffer'
|
24
|
+
require 'concurrent/actor/behaviour/errors_on_unknown_message'
|
25
|
+
require 'concurrent/actor/behaviour/executes_context'
|
26
|
+
require 'concurrent/actor/behaviour/linking'
|
27
|
+
require 'concurrent/actor/behaviour/pausing'
|
28
|
+
require 'concurrent/actor/behaviour/removes_child'
|
29
|
+
require 'concurrent/actor/behaviour/sets_results'
|
30
|
+
require 'concurrent/actor/behaviour/supervised'
|
31
|
+
require 'concurrent/actor/behaviour/supervising'
|
32
|
+
require 'concurrent/actor/behaviour/termination'
|
33
|
+
require 'concurrent/actor/behaviour/terminates_children'
|
34
|
+
|
35
|
+
def self.basic_behaviour_definition
|
36
|
+
[*base,
|
37
|
+
*user_messages(:terminate!)]
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.restarting_behaviour_definition
|
41
|
+
[*base,
|
42
|
+
*supervised,
|
43
|
+
[Behaviour::Supervising, [:reset!, :one_for_one]],
|
44
|
+
*user_messages(:pause!)]
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.base
|
48
|
+
[[SetResults, [:terminate!]],
|
49
|
+
# has to be before Termination to be able to remove children form terminated actor
|
50
|
+
[RemovesChild, []],
|
51
|
+
[Termination, []],
|
52
|
+
[TerminatesChildren, []],
|
53
|
+
[Linking, []]]
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.supervised
|
57
|
+
[[Supervised, []],
|
58
|
+
[Pausing, []]]
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.user_messages(on_error)
|
62
|
+
[[Buffer, []],
|
63
|
+
[SetResults, [on_error]],
|
64
|
+
[Awaits, []],
|
65
|
+
[ExecutesContext, []],
|
66
|
+
[ErrorsOnUnknownMessage, []]]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|