concurrent-ruby 0.8.0.pre2-java → 0.9.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +114 -3
- data/README.md +111 -55
- data/lib/concurrent.rb +90 -14
- data/lib/concurrent/async.rb +143 -51
- data/lib/concurrent/atom.rb +131 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +57 -107
- data/lib/concurrent/atomic/atomic_fixnum.rb +73 -101
- data/lib/concurrent/atomic/atomic_reference.rb +49 -0
- data/lib/concurrent/atomic/condition.rb +23 -12
- data/lib/concurrent/atomic/count_down_latch.rb +23 -21
- data/lib/concurrent/atomic/cyclic_barrier.rb +47 -47
- data/lib/concurrent/atomic/event.rb +33 -42
- data/lib/concurrent/atomic/read_write_lock.rb +252 -0
- data/lib/concurrent/atomic/semaphore.rb +64 -89
- data/lib/concurrent/atomic/thread_local_var.rb +130 -58
- data/lib/concurrent/atomic/thread_local_var/weak_key_map.rb +236 -0
- data/lib/concurrent/atomic_reference/direct_update.rb +34 -3
- data/lib/concurrent/atomic_reference/jruby.rb +6 -3
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +17 -39
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +3 -0
- data/lib/concurrent/atomic_reference/rbx.rb +4 -1
- data/lib/concurrent/atomic_reference/ruby.rb +6 -3
- data/lib/concurrent/atomics.rb +74 -4
- data/lib/concurrent/collection/copy_on_notify_observer_set.rb +115 -0
- data/lib/concurrent/collection/copy_on_write_observer_set.rb +119 -0
- data/lib/concurrent/collection/priority_queue.rb +300 -245
- data/lib/concurrent/concern/deprecation.rb +34 -0
- data/lib/concurrent/concern/dereferenceable.rb +88 -0
- data/lib/concurrent/concern/logging.rb +27 -0
- data/lib/concurrent/concern/obligation.rb +228 -0
- data/lib/concurrent/concern/observable.rb +85 -0
- data/lib/concurrent/configuration.rb +234 -109
- data/lib/concurrent/dataflow.rb +2 -3
- data/lib/concurrent/delay.rb +141 -50
- data/lib/concurrent/edge.rb +30 -0
- data/lib/concurrent/errors.rb +19 -7
- data/lib/concurrent/exchanger.rb +25 -1
- data/lib/concurrent/executor/cached_thread_pool.rb +51 -33
- data/lib/concurrent/executor/executor.rb +46 -299
- data/lib/concurrent/executor/executor_service.rb +521 -0
- data/lib/concurrent/executor/fixed_thread_pool.rb +196 -23
- data/lib/concurrent/executor/immediate_executor.rb +9 -9
- data/lib/concurrent/executor/indirect_immediate_executor.rb +4 -3
- data/lib/concurrent/executor/java_single_thread_executor.rb +17 -16
- data/lib/concurrent/executor/java_thread_pool_executor.rb +55 -102
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +14 -16
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +250 -166
- data/lib/concurrent/executor/safe_task_executor.rb +5 -4
- data/lib/concurrent/executor/serialized_execution.rb +22 -18
- data/lib/concurrent/executor/{per_thread_executor.rb → simple_executor_service.rb} +29 -20
- data/lib/concurrent/executor/single_thread_executor.rb +32 -21
- data/lib/concurrent/executor/thread_pool_executor.rb +73 -60
- data/lib/concurrent/executor/timer_set.rb +96 -84
- data/lib/concurrent/executors.rb +1 -1
- data/lib/concurrent/future.rb +71 -38
- data/lib/concurrent/immutable_struct.rb +89 -0
- data/lib/concurrent/ivar.rb +152 -60
- data/lib/concurrent/lazy_register.rb +40 -20
- data/lib/concurrent/maybe.rb +226 -0
- data/lib/concurrent/mutable_struct.rb +227 -0
- data/lib/concurrent/mvar.rb +44 -43
- data/lib/concurrent/promise.rb +229 -136
- data/lib/concurrent/scheduled_task.rb +341 -43
- data/lib/concurrent/settable_struct.rb +127 -0
- data/lib/concurrent/synchronization.rb +17 -0
- data/lib/concurrent/synchronization/abstract_object.rb +163 -0
- data/lib/concurrent/synchronization/abstract_struct.rb +158 -0
- data/lib/concurrent/synchronization/condition.rb +53 -0
- data/lib/concurrent/synchronization/java_object.rb +34 -0
- data/lib/concurrent/synchronization/lock.rb +32 -0
- data/lib/concurrent/synchronization/monitor_object.rb +26 -0
- data/lib/concurrent/synchronization/mutex_object.rb +43 -0
- data/lib/concurrent/synchronization/object.rb +78 -0
- data/lib/concurrent/synchronization/rbx_object.rb +75 -0
- data/lib/concurrent/timer_task.rb +92 -103
- data/lib/concurrent/tvar.rb +42 -38
- data/lib/concurrent/utilities.rb +3 -1
- data/lib/concurrent/utility/at_exit.rb +97 -0
- data/lib/concurrent/utility/engine.rb +44 -0
- data/lib/concurrent/utility/monotonic_time.rb +59 -0
- data/lib/concurrent/utility/native_extension_loader.rb +56 -0
- data/lib/concurrent/utility/processor_counter.rb +156 -0
- data/lib/concurrent/utility/timeout.rb +18 -14
- data/lib/concurrent/utility/timer.rb +11 -6
- data/lib/concurrent/version.rb +2 -1
- data/lib/concurrent_ruby.rb +1 -0
- data/lib/concurrent_ruby_ext.jar +0 -0
- metadata +46 -66
- data/lib/concurrent/actor.rb +0 -103
- data/lib/concurrent/actor/behaviour.rb +0 -70
- data/lib/concurrent/actor/behaviour/abstract.rb +0 -48
- data/lib/concurrent/actor/behaviour/awaits.rb +0 -21
- data/lib/concurrent/actor/behaviour/buffer.rb +0 -54
- data/lib/concurrent/actor/behaviour/errors_on_unknown_message.rb +0 -12
- data/lib/concurrent/actor/behaviour/executes_context.rb +0 -18
- data/lib/concurrent/actor/behaviour/linking.rb +0 -45
- data/lib/concurrent/actor/behaviour/pausing.rb +0 -77
- data/lib/concurrent/actor/behaviour/removes_child.rb +0 -16
- data/lib/concurrent/actor/behaviour/sets_results.rb +0 -36
- data/lib/concurrent/actor/behaviour/supervised.rb +0 -59
- data/lib/concurrent/actor/behaviour/supervising.rb +0 -34
- data/lib/concurrent/actor/behaviour/terminates_children.rb +0 -13
- data/lib/concurrent/actor/behaviour/termination.rb +0 -54
- data/lib/concurrent/actor/context.rb +0 -154
- data/lib/concurrent/actor/core.rb +0 -217
- data/lib/concurrent/actor/default_dead_letter_handler.rb +0 -9
- data/lib/concurrent/actor/envelope.rb +0 -41
- data/lib/concurrent/actor/errors.rb +0 -27
- data/lib/concurrent/actor/internal_delegations.rb +0 -49
- data/lib/concurrent/actor/public_delegations.rb +0 -40
- data/lib/concurrent/actor/reference.rb +0 -81
- data/lib/concurrent/actor/root.rb +0 -37
- data/lib/concurrent/actor/type_check.rb +0 -48
- data/lib/concurrent/actor/utils.rb +0 -10
- data/lib/concurrent/actor/utils/ad_hoc.rb +0 -21
- data/lib/concurrent/actor/utils/balancer.rb +0 -42
- data/lib/concurrent/actor/utils/broadcast.rb +0 -52
- data/lib/concurrent/actor/utils/pool.rb +0 -59
- data/lib/concurrent/actress.rb +0 -3
- data/lib/concurrent/agent.rb +0 -209
- data/lib/concurrent/atomic.rb +0 -92
- data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +0 -118
- data/lib/concurrent/atomic/copy_on_write_observer_set.rb +0 -117
- data/lib/concurrent/atomic/synchronization.rb +0 -51
- data/lib/concurrent/channel/buffered_channel.rb +0 -85
- data/lib/concurrent/channel/channel.rb +0 -41
- data/lib/concurrent/channel/unbuffered_channel.rb +0 -35
- data/lib/concurrent/channel/waitable_list.rb +0 -40
- data/lib/concurrent/channels.rb +0 -5
- data/lib/concurrent/collection/blocking_ring_buffer.rb +0 -71
- data/lib/concurrent/collection/ring_buffer.rb +0 -59
- data/lib/concurrent/collections.rb +0 -3
- data/lib/concurrent/dereferenceable.rb +0 -108
- data/lib/concurrent/executor/java_cached_thread_pool.rb +0 -32
- data/lib/concurrent/executor/java_fixed_thread_pool.rb +0 -31
- data/lib/concurrent/executor/ruby_cached_thread_pool.rb +0 -29
- data/lib/concurrent/executor/ruby_fixed_thread_pool.rb +0 -32
- data/lib/concurrent/executor/ruby_thread_pool_worker.rb +0 -73
- data/lib/concurrent/logging.rb +0 -20
- data/lib/concurrent/obligation.rb +0 -171
- data/lib/concurrent/observable.rb +0 -73
- data/lib/concurrent/options_parser.rb +0 -48
- data/lib/concurrent/utility/processor_count.rb +0 -152
- data/lib/extension_helper.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94cc8d875af4081f3b01de2517796f79c43d4627
|
4
|
+
data.tar.gz: d07bab5b8c928d783d684604c7af23940cd87f7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c446e8f8dbd430177b94ff9a8652665bcd1bc13e8d3aad5194ac16cdf19ab83c9f26de49b3036fa2bff4ccc9f4adc6e2bdb75187b59a039d45109a0f5c880d9
|
7
|
+
data.tar.gz: 798f45059166050420b8b9e143615e0fce2b97f2c5a8a281e5953b86f97846bfd31b39f5b9602c45a17c34799bec0fad422d738a962d73bb42fa3cf0926df65e
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,110 @@
|
|
1
|
-
|
1
|
+
## Current Release v0.9.0 (10 July 2015)
|
2
|
+
|
3
|
+
* Updated `AtomicReference`
|
4
|
+
- `AtomicReference#try_update` now simply returns instead of raising exception
|
5
|
+
- `AtomicReference#try_update!` was added to raise exceptions if an update
|
6
|
+
fails. Note: this is the same behavior as the old `try_update`
|
7
|
+
* Pure Java implementations of
|
8
|
+
- `AtomicBoolean`
|
9
|
+
- `AtomicFixnum`
|
10
|
+
- `Semaphore`
|
11
|
+
* Fixed bug when pruning Ruby thread pools
|
12
|
+
* Fixed bug in time calculations within `ScheduledTask`
|
13
|
+
* Default `count` in `CountDownLatch` to 1
|
14
|
+
* Use monotonic clock for all timers via `Concurrent.monotonic_time`
|
15
|
+
- Use `Process.clock_gettime(Process::CLOCK_MONOTONIC)` when available
|
16
|
+
- Fallback to `java.lang.System.nanoTime()` on unsupported JRuby versions
|
17
|
+
- Pure Ruby implementation for everything else
|
18
|
+
- Effects `Concurrent.timer`, `Concurrent.timeout`, `TimerSet`, `TimerTask`, and `ScheduledTask`
|
19
|
+
* Deprecated all clock-time based timer scheduling
|
20
|
+
- Only support scheduling by delay
|
21
|
+
- Effects `Concurrent.timer`, `TimerSet`, and `ScheduledTask`
|
22
|
+
* Added new `ReadWriteLock` class
|
23
|
+
* Consistent `at_exit` behavior for Java and Ruby thread pools.
|
24
|
+
* Added `at_exit` handler to Ruby thread pools (already in Java thread pools)
|
25
|
+
- Ruby handler stores the object id and retrieves from `ObjectSpace`
|
26
|
+
- JRuby disables `ObjectSpace` by default so that handler stores the object reference
|
27
|
+
* Added a `:stop_on_exit` option to thread pools to enable/disable `at_exit` handler
|
28
|
+
* Updated thread pool docs to better explain shutting down thread pools
|
29
|
+
* Simpler `:executor` option syntax for all abstractions which support this option
|
30
|
+
* Added `Executor#auto_terminate?` predicate method (for thread pools)
|
31
|
+
* Added `at_exit` handler to `TimerSet`
|
32
|
+
* Simplified auto-termination of the global executors
|
33
|
+
- Can now disable auto-termination of global executors
|
34
|
+
- Added shutdown/kill/wait_for_termination variants for global executors
|
35
|
+
* Can now disable auto-termination for *all* executors (the nuclear option)
|
36
|
+
* Simplified auto-termination of the global executors
|
37
|
+
* Deprecated terms "task pool" and "operation pool"
|
38
|
+
- New terms are "io executor" and "fast executor"
|
39
|
+
- New functions added with new names
|
40
|
+
- Deprecation warnings added to functions referencing old names
|
41
|
+
* Moved all thread pool related functions from `Concurrent::Configuration` to `Concurrent`
|
42
|
+
- Old functions still exist with deprecation warnings
|
43
|
+
- New functions have updated names as appropriate
|
44
|
+
* All high-level abstractions default to the "io executor"
|
45
|
+
* Fixed bug in `Actor` causing it to prematurely warm global thread pools on gem load
|
46
|
+
- This also fixed a `RejectedExecutionError` bug when running with minitest/autorun via JRuby
|
47
|
+
* Moved global logger up to the `Concurrent` namespace and refactored the code
|
48
|
+
* Optimized the performance of `Delay`
|
49
|
+
- Fixed a bug in which no executor option on construction caused block execution on a global thread pool
|
50
|
+
* Numerous improvements and bug fixes to `TimerSet`
|
51
|
+
* Fixed deadlock of `Future` when the handler raises Exception
|
52
|
+
* Added shared specs for more classes
|
53
|
+
* New concurrency abstractions including:
|
54
|
+
- `Atom`
|
55
|
+
- `Maybe`
|
56
|
+
- `ImmutableStruct`
|
57
|
+
- `MutableStruct`
|
58
|
+
- `SettableStruct`
|
59
|
+
* Created an Edge gem for unstable abstractions including
|
60
|
+
- `Actor`
|
61
|
+
- `Agent`
|
62
|
+
- `Channel`
|
63
|
+
- `Exchanger`
|
64
|
+
- `LazyRegister`
|
65
|
+
- **new Future Framework** <http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge.html> - unified
|
66
|
+
implementation of Futures and Promises which combines Features of previous `Future`,
|
67
|
+
`Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively
|
68
|
+
new synchronization layer to make all the paths **lock-free** with exception of blocking threads on `#wait`.
|
69
|
+
It offers better performance and does not block threads when not required.
|
70
|
+
* Actor framework changes:
|
71
|
+
- fixed reset loop in Pool
|
72
|
+
- Pool can use any actor as a worker, abstract worker class is no longer needed.
|
73
|
+
- Actor events not have format `[:event_name, *payload]` instead of just the Symbol.
|
74
|
+
- Actor now uses new Future/Promise Framework instead of `IVar` for better interoperability
|
75
|
+
- Behaviour definition array was simplified to `[BehaviourClass1, [BehaviourClass2, *initialization_args]]`
|
76
|
+
- Linking behavior responds to :linked message by returning array of linked actors
|
77
|
+
- Supervised behavior is removed in favour of just Linking
|
78
|
+
- RestartingContext is supervised by default now, `supervise: true` is not required any more
|
79
|
+
- Events can be private and public, so far only difference is that Linking will
|
80
|
+
pass to linked actors only public messages. Adding private :restarting and
|
81
|
+
:resetting events which are send before the actor restarts or resets allowing
|
82
|
+
to add callbacks to cleanup current child actors.
|
83
|
+
- Print also object_id in Reference to_s
|
84
|
+
- Add AbstractContext#default_executor to be able to override executor class wide
|
85
|
+
- Add basic IO example
|
86
|
+
- Documentation somewhat improved
|
87
|
+
- All messages should have same priority. It's now possible to send `actor << job1 << job2 << :terminate!` and
|
88
|
+
be sure that both jobs are processed first.
|
89
|
+
* Refactored `Channel` to use newer synchronization objects
|
90
|
+
* Added `#reset` and `#cancel` methods to `TimerSet`
|
91
|
+
* Added `#cancel` method to `Future` and `ScheduledTask`
|
92
|
+
* Refactored `TimerSet` to use `ScheduledTask`
|
93
|
+
* Updated `Async` with a factory that initializes the object
|
94
|
+
* Deprecated `Concurrent.timer` and `Concurrent.timeout`
|
95
|
+
* Reduced max threads on pure-Ruby thread pools (abends around 14751 threads)
|
96
|
+
* Moved many private/internal classes/modules into "namespace" modules
|
97
|
+
* Removed brute-force killing of threads in tests
|
98
|
+
* Fixed a thread pool bug when the operating system cannot allocate more threads
|
99
|
+
|
100
|
+
### Release v0.8.0 (25 January 2015)
|
101
|
+
|
102
|
+
* C extension for MRI have been extracted into the `concurrent-ruby-ext` companion gem.
|
103
|
+
Please see the README for more detail.
|
104
|
+
* Better variable isolation in `Promise` and `Future` via an `:args` option
|
105
|
+
* Continued to update intermittently failing tests
|
106
|
+
|
107
|
+
### Release v0.7.2 (24 January 2015)
|
2
108
|
|
3
109
|
* New `Semaphore` class based on [java.util.concurrent.Semaphore](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html)
|
4
110
|
* New `Promise.all?` and `Promise.any?` class methods
|
@@ -6,11 +112,16 @@
|
|
6
112
|
* Thread pools still accept the `:overflow_policy` option but display a warning
|
7
113
|
* Thread pools now implement `fallback_policy` behavior when not running (rather than universally rejecting tasks)
|
8
114
|
* Fixed minor `set_deref_options` constructor bug in `Promise` class
|
115
|
+
* Fixed minor `require` bug in `ThreadLocalVar` class
|
116
|
+
* Fixed race condition bug in `TimerSet` class
|
117
|
+
* Fixed race condition bug in `TimerSet` class
|
118
|
+
* Fixed signal bug in `TimerSet#post` method
|
9
119
|
* Numerous non-functional updates to clear warning when running in debug mode
|
10
120
|
* Fixed more intermittently failing tests
|
11
121
|
* Tests now run on new Travis build environment
|
122
|
+
* Multiple documentation updates
|
12
123
|
|
13
|
-
|
124
|
+
### Release v0.7.1 (4 December 2014)
|
14
125
|
|
15
126
|
Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/issues/142) for more information on the next planned release.
|
16
127
|
|
@@ -55,7 +166,7 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
|
|
55
166
|
- `SerializedExecutionDelegator` for serializing *any* executor
|
56
167
|
* Updated `Async` with serialized execution
|
57
168
|
* Updated `ImmediateExecutor` and `PerThreadExecutor` with full executor service lifecycle
|
58
|
-
* Added a `Delay` to root `Actress` initialization
|
169
|
+
* Added a `Delay` to root `Actress` initialization
|
59
170
|
* Minor bug fixes to thread pools
|
60
171
|
* Refactored many intermittently failing specs
|
61
172
|
* Removed Java interop warning `executor.rb:148 warning: ambiguous Java methods found, using submit(java.lang.Runnable)`
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Concurrent Ruby
|
2
|
-
[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby) [![Build Status](https://travis-ci.org/ruby-concurrency/concurrent-ruby.svg?branch=master)](https://travis-ci.org/ruby-concurrency/concurrent-ruby) [![
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby) [![Build Status](https://travis-ci.org/ruby-concurrency/concurrent-ruby.svg?branch=master)](https://travis-ci.org/ruby-concurrency/concurrent-ruby) [![Build status](https://ci.appveyor.com/api/projects/status/iq8aboyuu3etad4w?svg=true)](https://ci.appveyor.com/project/rubyconcurrency/concurrent-ruby) [![Code Climate](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby.svg)](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby) [![Inline docs](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby.svg)](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby) [![Dependency Status](https://gemnasium.com/ruby-concurrency/concurrent-ruby.svg)](https://gemnasium.com/ruby-concurrency/concurrent-ruby) [![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT) [![Gitter chat](http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby)
|
3
3
|
|
4
4
|
<table>
|
5
5
|
<tr>
|
@@ -39,6 +39,7 @@
|
|
39
39
|
|
40
40
|
MRI 1.9.3, 2.0, 2.1, 2.2, JRuby (1.9 mode), and Rubinius 2.x are supported.
|
41
41
|
This gem should be fully compatible with any interpreter that is compliant with Ruby 1.9.3 or newer.
|
42
|
+
Java 8 is required for JRuby (Java 7 support is deprecated in version 0.9 and will be removed in 1.0).
|
42
43
|
|
43
44
|
## Features & Documentation
|
44
45
|
|
@@ -50,52 +51,91 @@ We also have a [mailing list](http://groups.google.com/group/concurrent-ruby).
|
|
50
51
|
|
51
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.
|
52
53
|
|
53
|
-
|
54
|
+
#### General-purpose Concurrency Abstractions
|
54
55
|
|
55
|
-
* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html): Implements the Actor Model, where concurrent actors exchange messages.
|
56
|
-
* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Agent.html): A single atomic value that represents an identity.
|
57
56
|
* [Async](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Async.html): A mixin module that provides simple asynchronous behavior to any standard class/object or object.
|
57
|
+
* [Atom](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Atom.html): A way to manage shared, synchronous, independent state.
|
58
58
|
* [Future](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Future.html): An asynchronous operation that produces a value.
|
59
|
-
* [Dataflow](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent
|
59
|
+
* [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
60
|
* [Promise](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promise.html): Similar to Futures, with more features.
|
61
61
|
* [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ScheduledTask.html): Like a Future scheduled for a specific future time.
|
62
62
|
* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html): A Thread that periodically wakes up to perform work at regular intervals.
|
63
|
-
* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Channel.html): Communicating Sequential Processes (CSP).
|
64
63
|
|
65
|
-
|
64
|
+
#### Thread-safe Value Objects
|
66
65
|
|
67
|
-
*
|
66
|
+
* `Maybe` A thread-safe, immutable object representing an optional value, based on
|
67
|
+
[Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html).
|
68
|
+
* `Delay` Lazy evaluation of a block yielding an immutable result. Based on Clojure's
|
69
|
+
[delay](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Delay.html).
|
68
70
|
|
69
|
-
|
71
|
+
#### Thread-safe Structures
|
70
72
|
|
71
|
-
|
72
|
-
* [CopyOnNotifyObserverSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CopyOnNotifyObserverSet.html)
|
73
|
-
* [CopyOnWriteObserverSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CopyOnWriteObserverSet.html)
|
73
|
+
Derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
|
74
74
|
|
75
|
-
|
75
|
+
* `ImmutableStruct` Immutable struct where values are set at construction and cannot be changed later.
|
76
|
+
* `MutableStruct` Synchronized, mutable struct where values can be safely changed at any time.
|
77
|
+
* `SettableStruct` Synchronized, write-once struct where values can be set at most once, either at construction or any time thereafter.
|
76
78
|
|
77
|
-
|
79
|
+
#### Java-inspired ThreadPools and Other Executors
|
78
80
|
|
79
|
-
* [
|
80
|
-
* [countdown latch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html)
|
81
|
-
* [cyclic barrier](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CyclicBarrier.html)
|
82
|
-
* [event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html)
|
83
|
-
* [exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html)
|
84
|
-
* [semaphore](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Semaphore.html)
|
85
|
-
* [timeout](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#timeout-class_method)
|
86
|
-
* [timer](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#timer-class_method)
|
81
|
+
* See [ThreadPool](http://ruby-concurrency.github.io/concurrent-ruby/file.thread_pools.html) overview, which also contains a list of other Executors available.
|
87
82
|
|
88
|
-
|
83
|
+
#### Thread Synchronization Classes and Algorithms
|
89
84
|
|
90
|
-
|
85
|
+
* [CountdownLatch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html)
|
86
|
+
* [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CyclicBarrier.html)
|
87
|
+
* [Event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html)
|
88
|
+
* [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Semaphore.html)
|
89
|
+
|
90
|
+
#### Thread-safe Variables
|
91
91
|
|
92
92
|
* [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicBoolean.html)
|
93
93
|
* [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicFixnum.html)
|
94
|
-
* AtomicReference
|
94
|
+
* [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutexAtomic.html)
|
95
95
|
* [I-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html) (IVar)
|
96
96
|
* [M-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html) (MVar)
|
97
|
-
* [
|
98
|
-
* [
|
97
|
+
* [Thread-local variables](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html)
|
98
|
+
* [Software transactional memory](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TVar.html) (TVar)
|
99
|
+
* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReadWriteLock.html)
|
100
|
+
|
101
|
+
### Edge Features
|
102
|
+
|
103
|
+
These are available in the `concurrent-ruby-edge` companion gem, installed with `gem install concurrent-ruby-edge`.
|
104
|
+
|
105
|
+
These features are under active development and may change frequently. They are expected not to
|
106
|
+
keep backward compatibility (there may also lack tests and documentation). Semantic versions will
|
107
|
+
be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to `concurrent-ruby` when final.
|
108
|
+
|
109
|
+
* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html):
|
110
|
+
Implements the Actor Model, where concurrent actors exchange messages.
|
111
|
+
* [new Future Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge.html) - new
|
112
|
+
unified implementation of Futures and Promises which combines Features of previous `Future`,
|
113
|
+
`Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively
|
114
|
+
new synchronization layer to make all the paths **lock-free** with exception of blocking threads on `#wait`.
|
115
|
+
It offers better performance and does not block threads when not required.
|
116
|
+
* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Agent.html): A single atomic value that represents an identity.
|
117
|
+
* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Channel.html):
|
118
|
+
Communicating Sequential Processes (CSP).
|
119
|
+
* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html)
|
120
|
+
* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LazyRegister.html)
|
121
|
+
* [New Future Promise Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge.html) - new
|
122
|
+
unified implementation of Futures and Promises which combines Features of previous `Future`,
|
123
|
+
`Promise`, `IVar`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively
|
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
|
+
|
128
|
+
|
129
|
+
#### Statuses:
|
130
|
+
|
131
|
+
*Why are these not in core?*
|
132
|
+
|
133
|
+
- **Actor** - Partial documentation and tests; stability is good.
|
134
|
+
- **Future/Promise Framework** - API changes; partial documentation and tests; stability good.
|
135
|
+
- **Agent** - Incomplete behaviour compared to Clojure's models; stability good.
|
136
|
+
- **Channel** - Missing documentation; limted features; stability good.
|
137
|
+
- **Exchanger** - Known race condition requiring a new implementation.
|
138
|
+
- **LazyRegister** - Missing documentation and tests.
|
99
139
|
|
100
140
|
## Usage
|
101
141
|
|
@@ -112,29 +152,39 @@ require 'concurrent' # everything
|
|
112
152
|
|
113
153
|
# groups
|
114
154
|
|
115
|
-
require 'concurrent/actor' # Concurrent::Actor and supporting code
|
116
155
|
require 'concurrent/atomics' # atomic and thread synchronization classes
|
117
|
-
require 'concurrent/channels' # Concurrent::Channel and supporting code
|
118
156
|
require 'concurrent/executors' # Thread pools and other executors
|
119
|
-
require 'concurrent/utilities' # utility methods such as processor count and timers
|
120
157
|
|
121
158
|
# individual abstractions
|
122
159
|
|
160
|
+
require 'concurrent/async' # Concurrent::Async
|
161
|
+
require 'concurrent/atom' # Concurrent::Atom
|
162
|
+
require 'concurrent/dataflow' # Concurrent::dataflow
|
163
|
+
require 'concurrent/delay' # Concurrent::Delay
|
164
|
+
require 'concurrent/future' # Concurrent::Future
|
165
|
+
require 'concurrent/immutable_struct' # Concurrent::ImmutableStruct
|
166
|
+
require 'concurrent/ivar' # Concurrent::IVar
|
167
|
+
require 'concurrent/maybe' # Concurrent::Maybe
|
168
|
+
require 'concurrent/mutable_struct' # Concurrent::MutableStruct
|
169
|
+
require 'concurrent/mvar' # Concurrent::MVar
|
170
|
+
require 'concurrent/promise' # Concurrent::Promise
|
171
|
+
require 'concurrent/scheduled_task' # Concurrent::ScheduledTask
|
172
|
+
require 'concurrent/settable_struct' # Concurrent::SettableStruct
|
173
|
+
require 'concurrent/timer_task' # Concurrent::TimerTask
|
174
|
+
require 'concurrent/tvar' # Concurrent::TVar
|
175
|
+
|
176
|
+
# experimental - available in `concurrent-ruby-edge` companion gem
|
177
|
+
|
178
|
+
require 'concurrent/actor' # Concurrent::Actor and supporting code
|
179
|
+
require 'concurrent/edge/future' # new Future Framework
|
123
180
|
require 'concurrent/agent' # Concurrent::Agent
|
124
|
-
require 'concurrent/
|
125
|
-
require 'concurrent/atomic' # Concurrent::Atomic (formerly the `atomic` gem)
|
126
|
-
require 'concurrent/dataflow' # Concurrent::dataflow
|
127
|
-
require 'concurrent/delay' # Concurrent::Delay
|
181
|
+
require 'concurrent/channel ' # Concurrent::Channel and supporting code
|
128
182
|
require 'concurrent/exchanger' # Concurrent::Exchanger
|
129
|
-
require 'concurrent/
|
130
|
-
require 'concurrent/ivar' # Concurrent::IVar
|
131
|
-
require 'concurrent/mvar' # Concurrent::MVar
|
132
|
-
require 'concurrent/promise' # Concurrent::Promise
|
133
|
-
require 'concurrent/scheduled_task' # Concurrent::ScheduledTask
|
134
|
-
require 'concurrent/timer_task' # Concurrent::TimerTask
|
135
|
-
require 'concurrent/tvar' # Concurrent::TVar
|
183
|
+
require 'concurrent/lazy_register' # Concurrent::LazyRegister
|
136
184
|
```
|
137
185
|
|
186
|
+
If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could help to reveal the problem.
|
187
|
+
|
138
188
|
## Installation
|
139
189
|
|
140
190
|
```shell
|
@@ -153,8 +203,8 @@ and run `bundle install` from your shell.
|
|
153
203
|
|
154
204
|
Potential performance improvements may be achieved under MRI by installing optional C extensions.
|
155
205
|
To minimize installation errors the C extensions are available in the `concurrent-ruby-ext` extension
|
156
|
-
gem.
|
157
|
-
Simply install the extension
|
206
|
+
gem. `concurrent-ruby` and `concurrent-ruby-ext` are always released together with same version.
|
207
|
+
Simply install the extension gem too:
|
158
208
|
|
159
209
|
```ruby
|
160
210
|
gem install concurrent-ruby-ext
|
@@ -191,34 +241,40 @@ any platform. *Documentation is forthcoming...*
|
|
191
241
|
|
192
242
|
```
|
193
243
|
*MRI only*
|
194
|
-
rake build:native # Build concurrent-ruby-ext-<version>-<platform>.gem into the pkg
|
195
|
-
rake compile:extension # Compile extension
|
244
|
+
bundle exec rake build:native # Build concurrent-ruby-ext-<version>-<platform>.gem into the pkg dir
|
245
|
+
bundle exec rake compile:extension # Compile extension
|
196
246
|
|
197
247
|
*JRuby only*
|
198
|
-
rake build # Build JRuby-specific core gem (alias for `build:core`)
|
199
|
-
rake build:core # Build concurrent-ruby-<version>-java.gem into the pkg directory
|
248
|
+
bundle exec rake build # Build JRuby-specific core gem (alias for `build:core`)
|
249
|
+
bundle exec rake build:core # Build concurrent-ruby-<version>-java.gem into the pkg directory
|
200
250
|
|
201
251
|
*All except JRuby*
|
202
|
-
rake build
|
203
|
-
rake build:
|
204
|
-
|
252
|
+
bundle exec rake build:core # Build concurrent-ruby-<version>.gem into the pkg directory
|
253
|
+
bundle exec rake build:ext # Build concurrent-ruby-ext-<version>.gem into the pkg directory
|
254
|
+
|
255
|
+
*When Docker IS installed*
|
256
|
+
bundle exec rake build:windows # Build the windows binary <version> gems per rake-compiler-dock
|
257
|
+
bundle exec rake build # Build core, extension, and edge gems, including Windows binaries
|
258
|
+
|
259
|
+
*When Docker is NOT installed*
|
260
|
+
bundle exec rake build # Build core, extension, and edge gems (excluding Windows binaries)
|
205
261
|
|
206
262
|
*All*
|
207
|
-
rake clean # Remove any temporary products
|
208
|
-
rake clobber # Remove any generated file
|
209
|
-
rake compile # Compile all the extensions
|
263
|
+
bundle exec rake clean # Remove any temporary products
|
264
|
+
bundle exec rake clobber # Remove any generated file
|
265
|
+
bundle exec rake compile # Compile all the extensions
|
210
266
|
```
|
211
267
|
|
212
268
|
## Maintainers
|
213
269
|
|
214
|
-
* [Jerry D'Antonio](https://github.com/jdantonio)
|
270
|
+
* [Jerry D'Antonio](https://github.com/jdantonio) (creator)
|
215
271
|
* [Michele Della Torre](https://github.com/mighe)
|
216
272
|
* [Chris Seaton](https://github.com/chrisseaton)
|
217
273
|
* [Lucas Allan](https://github.com/lucasallan)
|
218
274
|
* [Petr Chalupa](https://github.com/pitr-ch)
|
219
275
|
* [Paweł Obrok](https://github.com/obrok)
|
220
276
|
|
221
|
-
|
277
|
+
## Contributing
|
222
278
|
|
223
279
|
1. Fork it
|
224
280
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
data/lib/concurrent.rb
CHANGED
@@ -1,39 +1,115 @@
|
|
1
1
|
require 'concurrent/version'
|
2
2
|
|
3
|
+
require 'concurrent/synchronization'
|
4
|
+
|
3
5
|
require 'concurrent/configuration'
|
4
6
|
|
5
7
|
require 'concurrent/atomics'
|
6
|
-
require 'concurrent/
|
7
|
-
require 'concurrent/collections'
|
8
|
+
require 'concurrent/errors'
|
8
9
|
require 'concurrent/executors'
|
9
10
|
require 'concurrent/utilities'
|
10
11
|
|
11
|
-
require 'concurrent/
|
12
|
-
require 'concurrent/
|
13
|
-
require 'concurrent/lazy_register'
|
14
|
-
require 'concurrent/agent'
|
12
|
+
require 'concurrent/atomic/atomic_reference'
|
13
|
+
require 'concurrent/atom'
|
15
14
|
require 'concurrent/async'
|
16
15
|
require 'concurrent/dataflow'
|
17
16
|
require 'concurrent/delay'
|
18
|
-
require 'concurrent/dereferenceable'
|
19
|
-
require 'concurrent/errors'
|
20
|
-
require 'concurrent/exchanger'
|
21
17
|
require 'concurrent/future'
|
18
|
+
require 'concurrent/immutable_struct'
|
22
19
|
require 'concurrent/ivar'
|
20
|
+
require 'concurrent/maybe'
|
21
|
+
require 'concurrent/mutable_struct'
|
23
22
|
require 'concurrent/mvar'
|
24
|
-
require 'concurrent/obligation'
|
25
|
-
require 'concurrent/observable'
|
26
|
-
require 'concurrent/options_parser'
|
27
23
|
require 'concurrent/promise'
|
28
24
|
require 'concurrent/scheduled_task'
|
25
|
+
require 'concurrent/settable_struct'
|
29
26
|
require 'concurrent/timer_task'
|
30
27
|
require 'concurrent/tvar'
|
31
28
|
|
29
|
+
# @!macro [new] internal_implementation_note
|
30
|
+
#
|
31
|
+
# @note **Private Implementation:** This abstraction is a private, internal
|
32
|
+
# implementation detail. It should never be used directly.
|
33
|
+
|
34
|
+
# @!macro [new] monotonic_clock_warning
|
35
|
+
#
|
36
|
+
# @note Time calculations one all platforms and languages are sensitive to
|
37
|
+
# changes to the system clock. To alleviate the potential problems
|
38
|
+
# associated with changing the system clock while an application is running,
|
39
|
+
# most modern operating systems provide a monotonic clock that operates
|
40
|
+
# independently of the system clock. A monotonic clock cannot be used to
|
41
|
+
# determine human-friendly clock times. A monotonic clock is used exclusively
|
42
|
+
# for calculating time intervals. Not all Ruby platforms provide access to an
|
43
|
+
# operating system monotonic clock. On these platforms a pure-Ruby monotonic
|
44
|
+
# clock will be used as a fallback. An operating system monotonic clock is both
|
45
|
+
# faster and more reliable than the pure-Ruby implementation. The pure-Ruby
|
46
|
+
# implementation should be fast and reliable enough for most non-realtime
|
47
|
+
# operations. At this time the common Ruby platforms that provide access to an
|
48
|
+
# operating system monotonic clock are MRI 2.1 and above and JRuby (all versions).
|
49
|
+
#
|
50
|
+
# @see http://linux.die.net/man/3/clock_gettime Linux clock_gettime(3)
|
51
|
+
|
52
|
+
# @!macro [new] copy_options
|
53
|
+
#
|
54
|
+
# ## Copy Options
|
55
|
+
#
|
56
|
+
# Object references in Ruby are mutable. This can lead to serious
|
57
|
+
# problems when the {#value} of an object is a mutable reference. Which
|
58
|
+
# is always the case unless the value is a `Fixnum`, `Symbol`, or similar
|
59
|
+
# "primative" data type. Each instance can be configured with a few
|
60
|
+
# options that can help protect the program from potentially dangerous
|
61
|
+
# operations. Each of these options can be optionally set when the oject
|
62
|
+
# instance is created:
|
63
|
+
#
|
64
|
+
# * `:dup_on_deref` When true the object will call the `#dup` method on
|
65
|
+
# the `value` object every time the `#value` methid is called
|
66
|
+
# (default: false)
|
67
|
+
# * `:freeze_on_deref` When true the object will call the `#freeze`
|
68
|
+
# method on the `value` object every time the `#value` method is called
|
69
|
+
# (default: false)
|
70
|
+
# * `:copy_on_deref` When given a `Proc` object the `Proc` will be run
|
71
|
+
# every time the `#value` method is called. The `Proc` will be given
|
72
|
+
# the current `value` as its only argument and the result returned by
|
73
|
+
# the block will be the return value of the `#value` call. When `nil`
|
74
|
+
# this option will be ignored (default: nil)
|
75
|
+
#
|
76
|
+
# When multiple deref options are set the order of operations is strictly defined.
|
77
|
+
# The order of deref operations is:
|
78
|
+
# * `:copy_on_deref`
|
79
|
+
# * `:dup_on_deref`
|
80
|
+
# * `:freeze_on_deref`
|
81
|
+
#
|
82
|
+
# Because of this ordering there is no need to `#freeze` an object created by a
|
83
|
+
# provided `:copy_on_deref` block. Simply set `:freeze_on_deref` to `true`.
|
84
|
+
# Setting both `:dup_on_deref` to `true` and `:freeze_on_deref` to `true` is
|
85
|
+
# as close to the behavior of a "pure" functional language (like Erlang, Clojure,
|
86
|
+
# or Haskell) as we are likely to get in Ruby.
|
87
|
+
|
88
|
+
# @!macro [attach] deref_options
|
89
|
+
#
|
90
|
+
# @option opts [Boolean] :dup_on_deref (false) Call `#dup` before
|
91
|
+
# returning the data from {#value}
|
92
|
+
# @option opts [Boolean] :freeze_on_deref (false) Call `#freeze` before
|
93
|
+
# returning the data from {#value}
|
94
|
+
# @option opts [Proc] :copy_on_deref (nil) When calling the {#value}
|
95
|
+
# method, call the given proc passing the internal value as the sole
|
96
|
+
# argument then return the new value returned from the proc.
|
97
|
+
|
98
|
+
# @!macro [attach] executor_and_deref_options
|
99
|
+
#
|
100
|
+
# @param [Hash] opts the options used to define the behavior at update and deref
|
101
|
+
# and to specify the executor on which to perform actions
|
102
|
+
# @option opts [Executor] :executor when set use the given `Executor` instance.
|
103
|
+
# Three special values are also supported: `:task` returns the global task pool,
|
104
|
+
# `:operation` returns the global operation pool, and `:immediate` returns a new
|
105
|
+
# `ImmediateExecutor` object.
|
106
|
+
# @!macro deref_options
|
107
|
+
|
32
108
|
# Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell,
|
33
109
|
# F#, C#, Java, and classic concurrency patterns.
|
34
|
-
#
|
110
|
+
#
|
35
111
|
# The design goals of this gem are:
|
36
|
-
#
|
112
|
+
#
|
37
113
|
# * Stay true to the spirit of the languages providing inspiration
|
38
114
|
# * But implement in a way that makes sense for Ruby
|
39
115
|
# * Keep the semantics as idiomatic Ruby as possible
|