concurrent-ruby-edge 0.1.0 → 0.1.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 +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
|
+
[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby)
|
4
|
+
[![Build Status](https://travis-ci.org/ruby-concurrency/concurrent-ruby.svg?branch=master)](https://travis-ci.org/ruby-concurrency/concurrent-ruby)
|
5
|
+
[![Build status](https://ci.appveyor.com/api/projects/status/iq8aboyuu3etad4w?svg=true)](https://ci.appveyor.com/project/rubyconcurrency/concurrent-ruby)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby.svg)](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby)
|
7
|
+
[![Inline docs](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby.svg)](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby)
|
8
|
+
[![Dependency Status](https://gemnasium.com/ruby-concurrency/concurrent-ruby.svg)](https://gemnasium.com/ruby-concurrency/concurrent-ruby)
|
9
|
+
[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
|
10
|
+
[![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-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
|