concurrent-ruby-edge 0.1.0 → 0.1.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 +23 -19
- data/lib/concurrent/actor/core.rb +1 -1
- data/lib/concurrent/actor/utils/pool.rb +1 -1
- data/lib/concurrent/edge/future.rb +18 -18
- data/lib/concurrent/edge/lock_free_linked_set.rb +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a3b78f7dce2948e4cb684345370e8383d9b179c
|
4
|
+
data.tar.gz: d4ffa926ffbeaf4a33d06b3384a4cea42df04934
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff2aa5ea7845498b082ab4e21b912f58fad92bea079cbb273c0973e2c4999c1e467bdaf7d0cf749ca44b40d5143dfc298eefa68e3e9a89ca7b0f808240e9d211
|
7
|
+
data.tar.gz: 777e75d09d3d2cd0962d601385bb6566bd77b4855f9ad3d56d49cafe485d3f5631772e5dd6b54969ee2a96ab898852207944d9e784f33063866023cc4ad348ee
|
data/README.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Concurrent Ruby
|
2
|
-
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/concurrent-ruby)
|
4
|
+
[](https://travis-ci.org/ruby-concurrency/concurrent-ruby)
|
5
|
+
[](https://ci.appveyor.com/project/rubyconcurrency/concurrent-ruby)
|
6
|
+
[](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby)
|
7
|
+
[](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby)
|
8
|
+
[](https://gemnasium.com/ruby-concurrency/concurrent-ruby)
|
9
|
+
[](http://opensource.org/licenses/MIT)
|
10
|
+
[-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby)
|
3
11
|
|
4
12
|
<table>
|
5
13
|
<tr>
|
@@ -43,13 +51,13 @@ Java 8 is required for JRuby (Java 7 support is deprecated in version 0.9 and wi
|
|
43
51
|
|
44
52
|
## Features & Documentation
|
45
53
|
|
46
|
-
We have a roadmap guiding our work toward the [v1.0.0 release](https://github.com/ruby-concurrency/concurrent-ruby/
|
54
|
+
We have a roadmap guiding our work toward the [v1.0.0 release](https://github.com/ruby-concurrency/concurrent-ruby/issues/257).
|
47
55
|
|
48
56
|
The primary site for documentation is the automatically generated [API documentation](http://ruby-concurrency.github.io/concurrent-ruby/frames.html)
|
49
57
|
|
50
|
-
We also have a [mailing list](http://groups.google.com/group/concurrent-ruby).
|
58
|
+
We also have a [mailing list](http://groups.google.com/group/concurrent-ruby) and [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby).
|
51
59
|
|
52
|
-
This library contains a variety of concurrency abstractions at high and low levels. One of the high-level abstractions is likely to meet most common needs.
|
60
|
+
This library contains a variety of concurrency abstractions at high and low levels. One of the high-level abstractions is likely to meet most common needs.
|
53
61
|
|
54
62
|
#### General-purpose Concurrency Abstractions
|
55
63
|
|
@@ -59,7 +67,7 @@ This library contains a variety of concurrency abstractions at high and low leve
|
|
59
67
|
* [Dataflow](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#dataflow-class_method): Built on Futures, Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available.
|
60
68
|
* [Promise](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promise.html): Similar to Futures, with more features.
|
61
69
|
* [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ScheduledTask.html): Like a Future scheduled for a specific future time.
|
62
|
-
* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html): A Thread that periodically wakes up to perform work at regular intervals.
|
70
|
+
* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html): A Thread that periodically wakes up to perform work at regular intervals.
|
63
71
|
|
64
72
|
#### Thread-safe Value Objects
|
65
73
|
|
@@ -97,6 +105,7 @@ Derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
|
|
97
105
|
* [Thread-local variables](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html)
|
98
106
|
* [Software transactional memory](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TVar.html) (TVar)
|
99
107
|
* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReadWriteLock.html)
|
108
|
+
* [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReentrantReadWriteLock.html)
|
100
109
|
|
101
110
|
### Edge Features
|
102
111
|
|
@@ -108,34 +117,31 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
|
|
108
117
|
|
109
118
|
* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html):
|
110
119
|
Implements the Actor Model, where concurrent actors exchange messages.
|
111
|
-
* [new Future Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge.html) - new
|
120
|
+
* [new Future Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/FutureShortcuts.html) - new
|
112
121
|
unified implementation of Futures and Promises which combines Features of previous `Future`,
|
113
122
|
`Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively
|
114
|
-
new synchronization layer to make all the
|
115
|
-
|
123
|
+
new synchronization layer to make all the features **non-blocking** and **lock-free** with exception of obviously blocking
|
124
|
+
operations like `#wait`, `#value`. It also offers better performance.
|
116
125
|
* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Agent.html): A single atomic value that represents an identity.
|
117
126
|
* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Channel.html):
|
118
127
|
Communicating Sequential Processes (CSP).
|
119
128
|
* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html)
|
120
129
|
* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LazyRegister.html)
|
121
|
-
* [
|
122
|
-
|
123
|
-
|
124
|
-
new synchronization layer to make all the paths lock-free with exception of blocking threads on `#wait`.
|
125
|
-
It offers better performance and does not block threads (exception being `#wait` and similar methods where it's
|
126
|
-
intended).
|
127
|
-
|
130
|
+
* [Atomic Markable Reference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/AtomicMarkableReference.html)
|
131
|
+
* [LockFreeLinked Set](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeLinkedSet.html)
|
132
|
+
* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeStack.html)
|
128
133
|
|
129
134
|
#### Statuses:
|
130
135
|
|
131
136
|
*Why are these not in core?*
|
132
137
|
|
133
|
-
- **Actor** - Partial documentation and tests; stability is good.
|
138
|
+
- **Actor** - Partial documentation and tests; stability is good.
|
134
139
|
- **Future/Promise Framework** - API changes; partial documentation and tests; stability good.
|
135
140
|
- **Agent** - Incomplete behaviour compared to Clojure's models; stability good.
|
136
141
|
- **Channel** - Missing documentation; limted features; stability good.
|
137
142
|
- **Exchanger** - Known race condition requiring a new implementation.
|
138
|
-
- **LazyRegister** - Missing documentation and tests.
|
143
|
+
- **LazyRegister** - Missing documentation and tests.
|
144
|
+
- **AtomicMarkableReference, LockFreeLinkedSet, LockFreeStack** - Needs real world battle testing
|
139
145
|
|
140
146
|
## Usage
|
141
147
|
|
@@ -179,8 +185,6 @@ require 'concurrent/actor' # Concurrent::Actor and supporting code
|
|
179
185
|
require 'concurrent/edge/future' # new Future Framework
|
180
186
|
require 'concurrent/agent' # Concurrent::Agent
|
181
187
|
require 'concurrent/channel ' # Concurrent::Channel and supporting code
|
182
|
-
require 'concurrent/exchanger' # Concurrent::Exchanger
|
183
|
-
require 'concurrent/lazy_register' # Concurrent::LazyRegister
|
184
188
|
```
|
185
189
|
|
186
190
|
If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could help to reveal the problem.
|
@@ -208,7 +208,7 @@ module Concurrent
|
|
208
208
|
end
|
209
209
|
|
210
210
|
def initialize_behaviours(opts)
|
211
|
-
@behaviour_definition = (Type! opts[:behaviour_definition] || @context.behaviour_definition, Array).each do |(behaviour,
|
211
|
+
@behaviour_definition = (Type! opts[:behaviour_definition] || @context.behaviour_definition, Array).each do |(behaviour, _)|
|
212
212
|
Child! behaviour, Behaviour::Abstract
|
213
213
|
end
|
214
214
|
@behaviours = {}
|
@@ -37,7 +37,7 @@ module Concurrent
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def on_message(message)
|
40
|
-
command,
|
40
|
+
command, _ = message
|
41
41
|
return if [:restarted, :reset, :resumed, :terminated].include? command # ignore events from supervised actors
|
42
42
|
|
43
43
|
envelope_to_redirect = if envelope.future
|
@@ -113,7 +113,7 @@ module Concurrent
|
|
113
113
|
# post job on executor
|
114
114
|
# @return [true, false]
|
115
115
|
def post_on(executor, *args, &job)
|
116
|
-
Concurrent.executor(executor).post
|
116
|
+
Concurrent.executor(executor).post(*args, &job)
|
117
117
|
end
|
118
118
|
|
119
119
|
# TODO add first(futures, count=count)
|
@@ -307,7 +307,7 @@ module Concurrent
|
|
307
307
|
# @!visibility private
|
308
308
|
def complete_with(state, raise_on_reassign = true)
|
309
309
|
if @State.compare_and_set(PENDING, state)
|
310
|
-
(state)
|
310
|
+
#(state)
|
311
311
|
# go to synchronized block only if there were waiting threads
|
312
312
|
synchronize { ns_broadcast } if @Waiters.clear
|
313
313
|
call_callbacks
|
@@ -323,7 +323,7 @@ module Concurrent
|
|
323
323
|
# @return [Array<AbstractPromise>]
|
324
324
|
def blocks
|
325
325
|
@Callbacks.each_with_object([]) do |callback, promises|
|
326
|
-
promises.push
|
326
|
+
promises.push(*(callback.select { |v| v.is_a? AbstractPromise }))
|
327
327
|
end
|
328
328
|
end
|
329
329
|
|
@@ -464,7 +464,7 @@ module Concurrent
|
|
464
464
|
# @!visibility private
|
465
465
|
class SuccessArray < Success
|
466
466
|
def apply(block)
|
467
|
-
block.call
|
467
|
+
block.call(*value)
|
468
468
|
end
|
469
469
|
end
|
470
470
|
|
@@ -520,7 +520,7 @@ module Concurrent
|
|
520
520
|
end
|
521
521
|
|
522
522
|
def apply(block)
|
523
|
-
block.call
|
523
|
+
block.call(*reason)
|
524
524
|
end
|
525
525
|
end
|
526
526
|
|
@@ -603,7 +603,7 @@ module Concurrent
|
|
603
603
|
raise 'obligation is not failed' unless failed?
|
604
604
|
reason = @State.get.reason
|
605
605
|
if reason.is_a?(Array)
|
606
|
-
reason.each { |e| log
|
606
|
+
reason.each { |e| log ERROR, 'Edge::Future', e }
|
607
607
|
Concurrent::Error.new 'multiple exceptions, inspect log'
|
608
608
|
else
|
609
609
|
reason.exception(*args)
|
@@ -776,14 +776,14 @@ module Concurrent
|
|
776
776
|
end
|
777
777
|
|
778
778
|
def pr_async_callback_on_success(state, executor, callback)
|
779
|
-
pr_with_async(executor, state, callback) do |
|
780
|
-
pr_callback_on_success
|
779
|
+
pr_with_async(executor, state, callback) do |st, cb|
|
780
|
+
pr_callback_on_success st, cb
|
781
781
|
end
|
782
782
|
end
|
783
783
|
|
784
784
|
def pr_async_callback_on_failure(state, executor, callback)
|
785
|
-
pr_with_async(executor, state, callback) do |
|
786
|
-
pr_callback_on_failure
|
785
|
+
pr_with_async(executor, state, callback) do |st, cb|
|
786
|
+
pr_callback_on_failure st, cb
|
787
787
|
end
|
788
788
|
end
|
789
789
|
|
@@ -804,8 +804,8 @@ module Concurrent
|
|
804
804
|
end
|
805
805
|
|
806
806
|
def pr_async_callback_on_completion(state, executor, callback)
|
807
|
-
pr_with_async(executor, state, callback) do |
|
808
|
-
pr_callback_on_completion
|
807
|
+
pr_with_async(executor, state, callback) do |st, cb|
|
808
|
+
pr_callback_on_completion st, cb
|
809
809
|
end
|
810
810
|
end
|
811
811
|
|
@@ -981,7 +981,7 @@ module Concurrent
|
|
981
981
|
@Countdown = AtomicFixnum.new countdown
|
982
982
|
|
983
983
|
super(future)
|
984
|
-
@BlockedBy.each { |
|
984
|
+
@BlockedBy.each { |f| f.add_callback :pr_callback_notify_blocked, self }
|
985
985
|
end
|
986
986
|
|
987
987
|
# @api private
|
@@ -1063,8 +1063,8 @@ module Concurrent
|
|
1063
1063
|
|
1064
1064
|
def on_completable(done_future)
|
1065
1065
|
if done_future.success?
|
1066
|
-
Concurrent.post_on(@Executor, done_future, @Task) do |
|
1067
|
-
evaluate_to lambda {
|
1066
|
+
Concurrent.post_on(@Executor, done_future, @Task) do |future, task|
|
1067
|
+
evaluate_to lambda { future.apply task }
|
1068
1068
|
end
|
1069
1069
|
else
|
1070
1070
|
complete_with done_future.internal_state
|
@@ -1082,8 +1082,8 @@ module Concurrent
|
|
1082
1082
|
|
1083
1083
|
def on_completable(done_future)
|
1084
1084
|
if done_future.failed?
|
1085
|
-
Concurrent.post_on(@Executor, done_future, @Task) do |
|
1086
|
-
evaluate_to lambda {
|
1085
|
+
Concurrent.post_on(@Executor, done_future, @Task) do |future, task|
|
1086
|
+
evaluate_to lambda { future.apply task }
|
1087
1087
|
end
|
1088
1088
|
else
|
1089
1089
|
complete_with done_future.internal_state
|
@@ -1097,7 +1097,7 @@ module Concurrent
|
|
1097
1097
|
|
1098
1098
|
def on_completable(done_future)
|
1099
1099
|
if Future === done_future
|
1100
|
-
Concurrent.post_on(@Executor, done_future, @Task) { |future, task| evaluate_to
|
1100
|
+
Concurrent.post_on(@Executor, done_future, @Task) { |future, task| evaluate_to(*future.result, task) }
|
1101
1101
|
else
|
1102
1102
|
Concurrent.post_on(@Executor, @Task) { |task| evaluate_to task }
|
1103
1103
|
end
|
@@ -123,8 +123,8 @@ module Concurrent
|
|
123
123
|
#
|
124
124
|
# An iterator to loop through the set.
|
125
125
|
#
|
126
|
-
# @
|
127
|
-
# @
|
126
|
+
# @yield [Object] each item in the set
|
127
|
+
# @yieldparam [Object] item the item you to remove from the set
|
128
128
|
#
|
129
129
|
# @return [Object] self: the linked set on which each was called
|
130
130
|
def each
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concurrent-ruby-edge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-08-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: concurrent-ruby
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.9.
|
21
|
+
version: 0.9.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 0.9.
|
28
|
+
version: 0.9.1
|
29
29
|
description: |
|
30
30
|
These features are under active development and may change frequently. They are expected not to
|
31
31
|
keep backward compatibility (there may also lack tests and documentation). Semantic versions will
|