concurrent-ruby-edge 0.3.1 → 0.7.0
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 +5 -5
- data/CHANGELOG.md +552 -0
- data/LICENSE.txt +18 -18
- data/README.md +261 -103
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/abstract.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/awaits.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/buffer.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/errors_on_unknown_message.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/executes_context.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/linking.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/pausing.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/removes_child.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/sets_results.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/supervising.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/termination.rb +3 -1
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour.rb +1 -1
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/context.rb +3 -1
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/core.rb +5 -4
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/default_dead_letter_handler.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/envelope.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/errors.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/internal_delegations.rb +3 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/reference.rb +9 -8
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/root.rb +3 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils/ad_hoc.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils/balancer.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils/broadcast.rb +1 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils/pool.rb +1 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor.rb +11 -6
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/base.rb +14 -14
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/dropping.rb +1 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/sliding.rb +1 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/unbuffered.rb +1 -1
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/tick.rb +1 -1
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel.rb +3 -2
- data/lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb +107 -0
- data/lib/concurrent-ruby-edge/concurrent/edge/channel.rb +453 -0
- data/lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb +1549 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/lock_free_linked_set/node.rb +2 -2
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/lock_free_linked_set.rb +8 -7
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/lock_free_queue.rb +2 -0
- data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/old_channel_integration.rb +2 -0
- data/lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb +184 -0
- data/lib/concurrent-ruby-edge/concurrent/edge/promises.rb +174 -0
- data/lib/concurrent-ruby-edge/concurrent/edge/throttle.rb +229 -0
- data/lib/concurrent-ruby-edge/concurrent/edge/version.rb +3 -0
- data/lib/concurrent-ruby-edge/concurrent/edge.rb +21 -0
- data/lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb +50 -0
- data/lib/concurrent-ruby-edge/concurrent/lazy_register.rb +83 -0
- data/lib/{concurrent-edge.rb → concurrent-ruby-edge/concurrent-edge.rb} +5 -4
- metadata +71 -67
- data/lib/concurrent/edge/atomic_markable_reference.rb +0 -184
- data/lib/concurrent/edge/cancellation.rb +0 -138
- data/lib/concurrent/edge/lock_free_stack.rb +0 -126
- data/lib/concurrent/edge/processing_actor.rb +0 -161
- data/lib/concurrent/edge/promises.rb +0 -2111
- data/lib/concurrent/edge/throttle.rb +0 -192
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/public_delegations.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/type_check.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/buffered.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/ticker.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/timer.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/after_clause.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/default_clause.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/error_clause.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/put_clause.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/take_clause.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector.rb +0 -0
- /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/lock_free_linked_set/window.rb +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Concurrent
|
|
2
|
+
|
|
3
|
+
# A submodule for unstable, highly experimental features that are likely to
|
|
4
|
+
# change often and which may never become part of the core gem. Also for
|
|
5
|
+
# new, experimental version of abstractions already in the core gem.
|
|
6
|
+
#
|
|
7
|
+
# Most new features should start in this module, clearly indicating the
|
|
8
|
+
# experimental and unstable nature of the feature. Once a feature becomes
|
|
9
|
+
# more stable and is a candidate for inclusion in the core gem it should
|
|
10
|
+
# be moved up to the `Concurrent` module, where it would reside once merged
|
|
11
|
+
# into the core gem.
|
|
12
|
+
#
|
|
13
|
+
# The only exception to this is for features which *replace* features from
|
|
14
|
+
# the core gem in ways that are breaking and not backward compatible. These
|
|
15
|
+
# features should remain in this module until merged into the core gem. This
|
|
16
|
+
# will prevent namespace collisions.
|
|
17
|
+
#
|
|
18
|
+
# @!macro warn.edge
|
|
19
|
+
module Edge
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'concurrent/synchronization/object'
|
|
2
|
+
require 'concurrent/executor/executor_service'
|
|
3
|
+
|
|
4
|
+
module Concurrent
|
|
5
|
+
|
|
6
|
+
# A delegating executor which modifies each task with arguments
|
|
7
|
+
# before the task is given to the target executor it delegates to.
|
|
8
|
+
# @example Count task executions
|
|
9
|
+
# counter = AtomicFixnum.new
|
|
10
|
+
# count_executions = WrappingExecutor.new Concurrent.global_io_executor do |*args, &task|
|
|
11
|
+
# [*args, -> *args { counter.increment; task.call *args }]
|
|
12
|
+
# end
|
|
13
|
+
# 10.times { count_executions.post { :do_something } }
|
|
14
|
+
# sleep 0.01
|
|
15
|
+
# counter.value #=> 10
|
|
16
|
+
class WrappingExecutor < Synchronization::Object
|
|
17
|
+
safe_initialization!
|
|
18
|
+
|
|
19
|
+
include ExecutorService
|
|
20
|
+
|
|
21
|
+
# @param [Executor] executor an executor to delegate the tasks to
|
|
22
|
+
# @yield [*args, &task] A function which can modify the task with arguments
|
|
23
|
+
# @yieldparam [Array<Object>] *args the arguments submitted with the tasks
|
|
24
|
+
# @yieldparam [block] &task the task submitted to the executor to be modified
|
|
25
|
+
# @yieldreturn [Array<Object>] a new arguments and task `[*args, task]` which are submitted to the target executor
|
|
26
|
+
def initialize(executor, &wrapper)
|
|
27
|
+
super()
|
|
28
|
+
@Wrapper = wrapper
|
|
29
|
+
@Executor = executor
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @!macro executor_service_method_post
|
|
33
|
+
#
|
|
34
|
+
# @see #initialize how the tasks can be modified
|
|
35
|
+
def post(*args, &task)
|
|
36
|
+
*args, task = @Wrapper.call(*args, &task)
|
|
37
|
+
@Executor.post(*args, &task)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @!macro executor_service_method_can_overflow_question
|
|
41
|
+
def can_overflow?
|
|
42
|
+
@Executor.can_overflow?
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @!macro executor_service_method_serialized_question
|
|
46
|
+
def serialized?
|
|
47
|
+
@Executor.serialized?
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'concurrent/atomic/atomic_reference'
|
|
2
|
+
require 'concurrent/delay'
|
|
3
|
+
|
|
4
|
+
module Concurrent
|
|
5
|
+
|
|
6
|
+
# Hash-like collection that store lazy evaluated values.
|
|
7
|
+
#
|
|
8
|
+
# @!macro warn.edge
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# register = Concurrent::LazyRegister.new
|
|
12
|
+
# #=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @Data=#<Concurrent::AtomicReference:0x007fd7ecd5e1e0>>
|
|
13
|
+
# register[:key]
|
|
14
|
+
# #=> nil
|
|
15
|
+
# register.add(:key) { Concurrent::Actor.spawn!(Actor::AdHoc, :ping) { -> message { message } } }
|
|
16
|
+
# #=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @Data=#<Concurrent::AtomicReference:0x007fd7ecd5e1e0>>
|
|
17
|
+
# register[:key]
|
|
18
|
+
# #=> #<Concurrent::Actor::Reference /ping (Concurrent::Actor::AdHoc)>
|
|
19
|
+
#
|
|
20
|
+
class LazyRegister < Synchronization::Object
|
|
21
|
+
|
|
22
|
+
attr_atomic(:data)
|
|
23
|
+
private :data, :data=, :swap_data, :compare_and_set_data, :update_data
|
|
24
|
+
|
|
25
|
+
def initialize
|
|
26
|
+
super
|
|
27
|
+
self.data = {}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Element reference. Retrieves the value object corresponding to the
|
|
31
|
+
# key object. Returns nil if the key is not found. Raises an exception
|
|
32
|
+
# if the stored item raised an exception when the block was evaluated.
|
|
33
|
+
#
|
|
34
|
+
# @param [Object] key
|
|
35
|
+
# @return [Object] value stored for the key or nil if the key is not found
|
|
36
|
+
#
|
|
37
|
+
# @raise Exception when the initialization block fails
|
|
38
|
+
def [](key)
|
|
39
|
+
delay = data[key]
|
|
40
|
+
delay ? delay.value! : nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Returns true if the given key is present.
|
|
44
|
+
#
|
|
45
|
+
# @param [Object] key
|
|
46
|
+
# @return [true, false] if the key is registered
|
|
47
|
+
def registered?(key)
|
|
48
|
+
data.key?(key)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
alias_method :key?, :registered?
|
|
52
|
+
alias_method :has_key?, :registered?
|
|
53
|
+
|
|
54
|
+
# Element assignment. Associates the value given by value with the
|
|
55
|
+
# key given by key.
|
|
56
|
+
#
|
|
57
|
+
# @param [Object] key
|
|
58
|
+
# @yield the object to store under the key
|
|
59
|
+
#
|
|
60
|
+
# @return [LazyRegister] self
|
|
61
|
+
def register(key, &block)
|
|
62
|
+
delay = Delay.new(executor: :immediate, &block)
|
|
63
|
+
update_data { |h| h.merge(key => delay) }
|
|
64
|
+
self
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
alias_method :add, :register
|
|
68
|
+
alias_method :store, :register
|
|
69
|
+
|
|
70
|
+
# Un-registers the object under key, realized or not.
|
|
71
|
+
#
|
|
72
|
+
# @param [Object] key
|
|
73
|
+
#
|
|
74
|
+
# @return [LazyRegister] self
|
|
75
|
+
def unregister(key)
|
|
76
|
+
update_data { |h| h.dup.tap { |j| j.delete(key) } }
|
|
77
|
+
self
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
alias_method :remove, :unregister
|
|
81
|
+
alias_method :delete, :unregister
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
require 'concurrent'
|
|
2
2
|
|
|
3
|
+
require 'concurrent/edge/version'
|
|
4
|
+
|
|
3
5
|
require 'concurrent/actor'
|
|
4
6
|
require 'concurrent/agent'
|
|
5
7
|
require 'concurrent/channel'
|
|
6
|
-
require 'concurrent/exchanger'
|
|
7
8
|
require 'concurrent/lazy_register'
|
|
9
|
+
require 'concurrent/executor/wrapping_executor'
|
|
8
10
|
|
|
9
|
-
require 'concurrent/edge/atomic_markable_reference'
|
|
10
11
|
require 'concurrent/edge/lock_free_linked_set'
|
|
11
12
|
require 'concurrent/edge/lock_free_queue'
|
|
12
|
-
require 'concurrent/edge/lock_free_stack'
|
|
13
13
|
|
|
14
|
-
require 'concurrent/edge/promises'
|
|
15
14
|
require 'concurrent/edge/cancellation'
|
|
16
15
|
require 'concurrent/edge/throttle'
|
|
16
|
+
require 'concurrent/edge/channel'
|
|
17
17
|
|
|
18
18
|
require 'concurrent/edge/processing_actor'
|
|
19
|
+
require 'concurrent/edge/erlang_actor'
|
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.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jerry D'Antonio
|
|
@@ -10,22 +10,22 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2023-01-23 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: concurrent-ruby
|
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
|
18
18
|
requirements:
|
|
19
|
-
- -
|
|
19
|
+
- - "~>"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.0
|
|
21
|
+
version: 1.2.0
|
|
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: 1.0
|
|
28
|
+
version: 1.2.0
|
|
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
|
|
@@ -37,65 +37,71 @@ extensions: []
|
|
|
37
37
|
extra_rdoc_files:
|
|
38
38
|
- README.md
|
|
39
39
|
- LICENSE.txt
|
|
40
|
+
- CHANGELOG.md
|
|
40
41
|
files:
|
|
42
|
+
- CHANGELOG.md
|
|
41
43
|
- LICENSE.txt
|
|
42
44
|
- README.md
|
|
43
|
-
- lib/concurrent-edge.rb
|
|
44
|
-
- lib/concurrent/actor.rb
|
|
45
|
-
- lib/concurrent/actor/behaviour.rb
|
|
46
|
-
- lib/concurrent/actor/behaviour/abstract.rb
|
|
47
|
-
- lib/concurrent/actor/behaviour/awaits.rb
|
|
48
|
-
- lib/concurrent/actor/behaviour/buffer.rb
|
|
49
|
-
- lib/concurrent/actor/behaviour/errors_on_unknown_message.rb
|
|
50
|
-
- lib/concurrent/actor/behaviour/executes_context.rb
|
|
51
|
-
- lib/concurrent/actor/behaviour/linking.rb
|
|
52
|
-
- lib/concurrent/actor/behaviour/pausing.rb
|
|
53
|
-
- lib/concurrent/actor/behaviour/removes_child.rb
|
|
54
|
-
- lib/concurrent/actor/behaviour/sets_results.rb
|
|
55
|
-
- lib/concurrent/actor/behaviour/supervising.rb
|
|
56
|
-
- lib/concurrent/actor/behaviour/termination.rb
|
|
57
|
-
- lib/concurrent/actor/context.rb
|
|
58
|
-
- lib/concurrent/actor/core.rb
|
|
59
|
-
- lib/concurrent/actor/default_dead_letter_handler.rb
|
|
60
|
-
- lib/concurrent/actor/envelope.rb
|
|
61
|
-
- lib/concurrent/actor/errors.rb
|
|
62
|
-
- lib/concurrent/actor/internal_delegations.rb
|
|
63
|
-
- lib/concurrent/actor/public_delegations.rb
|
|
64
|
-
- lib/concurrent/actor/reference.rb
|
|
65
|
-
- lib/concurrent/actor/root.rb
|
|
66
|
-
- lib/concurrent/actor/type_check.rb
|
|
67
|
-
- lib/concurrent/actor/utils.rb
|
|
68
|
-
- lib/concurrent/actor/utils/ad_hoc.rb
|
|
69
|
-
- lib/concurrent/actor/utils/balancer.rb
|
|
70
|
-
- lib/concurrent/actor/utils/broadcast.rb
|
|
71
|
-
- lib/concurrent/actor/utils/pool.rb
|
|
72
|
-
- lib/concurrent/channel.rb
|
|
73
|
-
- lib/concurrent/channel/buffer.rb
|
|
74
|
-
- lib/concurrent/channel/buffer/base.rb
|
|
75
|
-
- lib/concurrent/channel/buffer/buffered.rb
|
|
76
|
-
- lib/concurrent/channel/buffer/dropping.rb
|
|
77
|
-
- lib/concurrent/channel/buffer/sliding.rb
|
|
78
|
-
- lib/concurrent/channel/buffer/ticker.rb
|
|
79
|
-
- lib/concurrent/channel/buffer/timer.rb
|
|
80
|
-
- lib/concurrent/channel/buffer/unbuffered.rb
|
|
81
|
-
- lib/concurrent/channel/selector.rb
|
|
82
|
-
- lib/concurrent/channel/selector/after_clause.rb
|
|
83
|
-
- lib/concurrent/channel/selector/default_clause.rb
|
|
84
|
-
- lib/concurrent/channel/selector/error_clause.rb
|
|
85
|
-
- lib/concurrent/channel/selector/put_clause.rb
|
|
86
|
-
- lib/concurrent/channel/selector/take_clause.rb
|
|
87
|
-
- lib/concurrent/channel/tick.rb
|
|
88
|
-
- lib/concurrent/edge
|
|
89
|
-
- lib/concurrent/edge/cancellation.rb
|
|
90
|
-
- lib/concurrent/edge/
|
|
91
|
-
- lib/concurrent/edge/
|
|
92
|
-
- lib/concurrent/edge/lock_free_linked_set
|
|
93
|
-
- lib/concurrent/edge/
|
|
94
|
-
- lib/concurrent/edge/
|
|
95
|
-
- lib/concurrent/edge/
|
|
96
|
-
- lib/concurrent/edge/
|
|
97
|
-
- lib/concurrent/edge/
|
|
98
|
-
- lib/concurrent/edge/
|
|
45
|
+
- lib/concurrent-ruby-edge/concurrent-edge.rb
|
|
46
|
+
- lib/concurrent-ruby-edge/concurrent/actor.rb
|
|
47
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb
|
|
48
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb
|
|
49
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/awaits.rb
|
|
50
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb
|
|
51
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/errors_on_unknown_message.rb
|
|
52
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/executes_context.rb
|
|
53
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb
|
|
54
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb
|
|
55
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/removes_child.rb
|
|
56
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/sets_results.rb
|
|
57
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/supervising.rb
|
|
58
|
+
- lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb
|
|
59
|
+
- lib/concurrent-ruby-edge/concurrent/actor/context.rb
|
|
60
|
+
- lib/concurrent-ruby-edge/concurrent/actor/core.rb
|
|
61
|
+
- lib/concurrent-ruby-edge/concurrent/actor/default_dead_letter_handler.rb
|
|
62
|
+
- lib/concurrent-ruby-edge/concurrent/actor/envelope.rb
|
|
63
|
+
- lib/concurrent-ruby-edge/concurrent/actor/errors.rb
|
|
64
|
+
- lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb
|
|
65
|
+
- lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb
|
|
66
|
+
- lib/concurrent-ruby-edge/concurrent/actor/reference.rb
|
|
67
|
+
- lib/concurrent-ruby-edge/concurrent/actor/root.rb
|
|
68
|
+
- lib/concurrent-ruby-edge/concurrent/actor/type_check.rb
|
|
69
|
+
- lib/concurrent-ruby-edge/concurrent/actor/utils.rb
|
|
70
|
+
- lib/concurrent-ruby-edge/concurrent/actor/utils/ad_hoc.rb
|
|
71
|
+
- lib/concurrent-ruby-edge/concurrent/actor/utils/balancer.rb
|
|
72
|
+
- lib/concurrent-ruby-edge/concurrent/actor/utils/broadcast.rb
|
|
73
|
+
- lib/concurrent-ruby-edge/concurrent/actor/utils/pool.rb
|
|
74
|
+
- lib/concurrent-ruby-edge/concurrent/channel.rb
|
|
75
|
+
- lib/concurrent-ruby-edge/concurrent/channel/buffer.rb
|
|
76
|
+
- lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb
|
|
77
|
+
- lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb
|
|
78
|
+
- lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb
|
|
79
|
+
- lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb
|
|
80
|
+
- lib/concurrent-ruby-edge/concurrent/channel/buffer/ticker.rb
|
|
81
|
+
- lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb
|
|
82
|
+
- lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb
|
|
83
|
+
- lib/concurrent-ruby-edge/concurrent/channel/selector.rb
|
|
84
|
+
- lib/concurrent-ruby-edge/concurrent/channel/selector/after_clause.rb
|
|
85
|
+
- lib/concurrent-ruby-edge/concurrent/channel/selector/default_clause.rb
|
|
86
|
+
- lib/concurrent-ruby-edge/concurrent/channel/selector/error_clause.rb
|
|
87
|
+
- lib/concurrent-ruby-edge/concurrent/channel/selector/put_clause.rb
|
|
88
|
+
- lib/concurrent-ruby-edge/concurrent/channel/selector/take_clause.rb
|
|
89
|
+
- lib/concurrent-ruby-edge/concurrent/channel/tick.rb
|
|
90
|
+
- lib/concurrent-ruby-edge/concurrent/edge.rb
|
|
91
|
+
- lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb
|
|
92
|
+
- lib/concurrent-ruby-edge/concurrent/edge/channel.rb
|
|
93
|
+
- lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
|
|
94
|
+
- lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb
|
|
95
|
+
- lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb
|
|
96
|
+
- lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb
|
|
97
|
+
- lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb
|
|
98
|
+
- lib/concurrent-ruby-edge/concurrent/edge/old_channel_integration.rb
|
|
99
|
+
- lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb
|
|
100
|
+
- lib/concurrent-ruby-edge/concurrent/edge/promises.rb
|
|
101
|
+
- lib/concurrent-ruby-edge/concurrent/edge/throttle.rb
|
|
102
|
+
- lib/concurrent-ruby-edge/concurrent/edge/version.rb
|
|
103
|
+
- lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb
|
|
104
|
+
- lib/concurrent-ruby-edge/concurrent/lazy_register.rb
|
|
99
105
|
homepage: http://www.concurrent-ruby.com
|
|
100
106
|
licenses:
|
|
101
107
|
- MIT
|
|
@@ -103,22 +109,20 @@ metadata: {}
|
|
|
103
109
|
post_install_message:
|
|
104
110
|
rdoc_options: []
|
|
105
111
|
require_paths:
|
|
106
|
-
- lib
|
|
112
|
+
- lib/concurrent-ruby-edge
|
|
107
113
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
114
|
requirements:
|
|
109
115
|
- - ">="
|
|
110
116
|
- !ruby/object:Gem::Version
|
|
111
|
-
version:
|
|
117
|
+
version: '2.3'
|
|
112
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
119
|
requirements:
|
|
114
120
|
- - ">="
|
|
115
121
|
- !ruby/object:Gem::Version
|
|
116
122
|
version: '0'
|
|
117
123
|
requirements: []
|
|
118
|
-
|
|
119
|
-
rubygems_version: 2.6.8
|
|
124
|
+
rubygems_version: 3.3.26
|
|
120
125
|
signing_key:
|
|
121
126
|
specification_version: 4
|
|
122
127
|
summary: Edge features and additions to the concurrent-ruby gem.
|
|
123
128
|
test_files: []
|
|
124
|
-
has_rdoc:
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
module Concurrent
|
|
2
|
-
module Edge
|
|
3
|
-
|
|
4
|
-
# @!macro [attach] atomic_markable_reference
|
|
5
|
-
#
|
|
6
|
-
# An atomic reference which maintains an object reference along with a mark bit
|
|
7
|
-
# that can be updated atomically.
|
|
8
|
-
#
|
|
9
|
-
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicMarkableReference.html
|
|
10
|
-
# java.util.concurrent.atomic.AtomicMarkableReference
|
|
11
|
-
class AtomicMarkableReference < ::Concurrent::Synchronization::Object
|
|
12
|
-
|
|
13
|
-
private(*attr_atomic(:reference))
|
|
14
|
-
|
|
15
|
-
# @!macro [attach] atomic_markable_reference_method_initialize
|
|
16
|
-
def initialize(value = nil, mark = false)
|
|
17
|
-
super()
|
|
18
|
-
self.reference = ImmutableArray[value, mark]
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# @!macro [attach] atomic_markable_reference_method_compare_and_set
|
|
22
|
-
#
|
|
23
|
-
# Atomically sets the value and mark to the given updated value and
|
|
24
|
-
# mark given both:
|
|
25
|
-
# - the current value == the expected value &&
|
|
26
|
-
# - the current mark == the expected mark
|
|
27
|
-
#
|
|
28
|
-
# @param [Object] expected_val the expected value
|
|
29
|
-
# @param [Object] new_val the new value
|
|
30
|
-
# @param [Boolean] expected_mark the expected mark
|
|
31
|
-
# @param [Boolean] new_mark the new mark
|
|
32
|
-
#
|
|
33
|
-
# @return [Boolean] `true` if successful. A `false` return indicates
|
|
34
|
-
# that the actual value was not equal to the expected value or the
|
|
35
|
-
# actual mark was not equal to the expected mark
|
|
36
|
-
def compare_and_set(expected_val, new_val, expected_mark, new_mark)
|
|
37
|
-
# Memoize a valid reference to the current AtomicReference for
|
|
38
|
-
# later comparison.
|
|
39
|
-
current = reference
|
|
40
|
-
curr_val, curr_mark = current
|
|
41
|
-
|
|
42
|
-
# Ensure that that the expected marks match.
|
|
43
|
-
return false unless expected_mark == curr_mark
|
|
44
|
-
|
|
45
|
-
if expected_val.is_a? Numeric
|
|
46
|
-
# If the object is a numeric, we need to ensure we are comparing
|
|
47
|
-
# the numerical values
|
|
48
|
-
return false unless expected_val == curr_val
|
|
49
|
-
else
|
|
50
|
-
# Otherwise, we need to ensure we are comparing the object identity.
|
|
51
|
-
# Theoretically, this could be incorrect if a user monkey-patched
|
|
52
|
-
# `Object#equal?`, but they should know that they are playing with
|
|
53
|
-
# fire at that point.
|
|
54
|
-
return false unless expected_val.equal? curr_val
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
prospect = ImmutableArray[new_val, new_mark]
|
|
58
|
-
|
|
59
|
-
compare_and_set_reference current, prospect
|
|
60
|
-
end
|
|
61
|
-
alias_method :compare_and_swap, :compare_and_set
|
|
62
|
-
|
|
63
|
-
# @!macro [attach] atomic_markable_reference_method_get
|
|
64
|
-
#
|
|
65
|
-
# Gets the current reference and marked values.
|
|
66
|
-
#
|
|
67
|
-
# @return [ImmutableArray] the current reference and marked values
|
|
68
|
-
def get
|
|
69
|
-
reference
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# @!macro [attach] atomic_markable_reference_method_value
|
|
73
|
-
#
|
|
74
|
-
# Gets the current value of the reference
|
|
75
|
-
#
|
|
76
|
-
# @return [Object] the current value of the reference
|
|
77
|
-
def value
|
|
78
|
-
reference[0]
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# @!macro [attach] atomic_markable_reference_method_mark
|
|
82
|
-
#
|
|
83
|
-
# Gets the current marked value
|
|
84
|
-
#
|
|
85
|
-
# @return [Boolean] the current marked value
|
|
86
|
-
def mark
|
|
87
|
-
reference[1]
|
|
88
|
-
end
|
|
89
|
-
alias_method :marked?, :mark
|
|
90
|
-
|
|
91
|
-
# @!macro [attach] atomic_markable_reference_method_set
|
|
92
|
-
#
|
|
93
|
-
# _Unconditionally_ sets to the given value of both the reference and
|
|
94
|
-
# the mark.
|
|
95
|
-
#
|
|
96
|
-
# @param [Object] new_val the new value
|
|
97
|
-
# @param [Boolean] new_mark the new mark
|
|
98
|
-
#
|
|
99
|
-
# @return [ImmutableArray] both the new value and the new mark
|
|
100
|
-
def set(new_val, new_mark)
|
|
101
|
-
self.reference = ImmutableArray[new_val, new_mark]
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# @!macro [attach] atomic_markable_reference_method_update
|
|
105
|
-
#
|
|
106
|
-
# Pass the current value and marked state to the given block, replacing it
|
|
107
|
-
# with the block's results. May retry if the value changes during the
|
|
108
|
-
# block's execution.
|
|
109
|
-
#
|
|
110
|
-
# @yield [Object] Calculate a new value and marked state for the atomic
|
|
111
|
-
# reference using given (old) value and (old) marked
|
|
112
|
-
# @yieldparam [Object] old_val the starting value of the atomic reference
|
|
113
|
-
# @yieldparam [Boolean] old_mark the starting state of marked
|
|
114
|
-
#
|
|
115
|
-
# @return [ImmutableArray] the new value and new mark
|
|
116
|
-
def update
|
|
117
|
-
loop do
|
|
118
|
-
old_val, old_mark = reference
|
|
119
|
-
new_val, new_mark = yield old_val, old_mark
|
|
120
|
-
|
|
121
|
-
if compare_and_set old_val, new_val, old_mark, new_mark
|
|
122
|
-
return ImmutableArray[new_val, new_mark]
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
# @!macro [attach] atomic_markable_reference_method_try_update!
|
|
128
|
-
#
|
|
129
|
-
# Pass the current value to the given block, replacing it
|
|
130
|
-
# with the block's result. Raise an exception if the update
|
|
131
|
-
# fails.
|
|
132
|
-
#
|
|
133
|
-
# @yield [Object] Calculate a new value and marked state for the atomic
|
|
134
|
-
# reference using given (old) value and (old) marked
|
|
135
|
-
# @yieldparam [Object] old_val the starting value of the atomic reference
|
|
136
|
-
# @yieldparam [Boolean] old_mark the starting state of marked
|
|
137
|
-
#
|
|
138
|
-
# @return [ImmutableArray] the new value and marked state
|
|
139
|
-
#
|
|
140
|
-
# @raise [Concurrent::ConcurrentUpdateError] if the update fails
|
|
141
|
-
def try_update!
|
|
142
|
-
old_val, old_mark = reference
|
|
143
|
-
new_val, new_mark = yield old_val, old_mark
|
|
144
|
-
|
|
145
|
-
unless compare_and_set old_val, new_val, old_mark, new_mark
|
|
146
|
-
fail ::Concurrent::ConcurrentUpdateError,
|
|
147
|
-
'AtomicMarkableReference: Update failed due to race condition.',
|
|
148
|
-
'Note: If you would like to guarantee an update, please use ' \
|
|
149
|
-
'the `AtomicMarkableReference#update` method.'
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
ImmutableArray[new_val, new_mark]
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# @!macro [attach] atomic_markable_reference_method_try_update
|
|
156
|
-
#
|
|
157
|
-
# Pass the current value to the given block, replacing it with the
|
|
158
|
-
# block's result. Simply return nil if update fails.
|
|
159
|
-
#
|
|
160
|
-
# @yield [Object] Calculate a new value and marked state for the atomic
|
|
161
|
-
# reference using given (old) value and (old) marked
|
|
162
|
-
# @yieldparam [Object] old_val the starting value of the atomic reference
|
|
163
|
-
# @yieldparam [Boolean] old_mark the starting state of marked
|
|
164
|
-
#
|
|
165
|
-
# @return [ImmutableArray] the new value and marked state, or nil if
|
|
166
|
-
# the update failed
|
|
167
|
-
def try_update
|
|
168
|
-
old_val, old_mark = reference
|
|
169
|
-
new_val, new_mark = yield old_val, old_mark
|
|
170
|
-
|
|
171
|
-
return unless compare_and_set old_val, new_val, old_mark, new_mark
|
|
172
|
-
|
|
173
|
-
ImmutableArray[new_val, new_mark]
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
# Internal/private ImmutableArray for representing pairs
|
|
177
|
-
class ImmutableArray < ::Array
|
|
178
|
-
def self.new(*args)
|
|
179
|
-
super(*args).freeze
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|