concurrent-ruby-edge 0.3.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,192 +0,0 @@
|
|
1
|
-
module Concurrent
|
2
|
-
# @!macro [new] throttle.example.throttled_block
|
3
|
-
# @example
|
4
|
-
# max_two = Throttle.new 2
|
5
|
-
# 10.times.map do
|
6
|
-
# Thread.new do
|
7
|
-
# max_two.throttled_block do
|
8
|
-
# # Only 2 at the same time
|
9
|
-
# do_stuff
|
10
|
-
# end
|
11
|
-
# end
|
12
|
-
# end
|
13
|
-
# @!macro [new] throttle.example.throttled_future
|
14
|
-
# @example
|
15
|
-
# throttle.throttled_future(1) do |arg|
|
16
|
-
# arg.succ
|
17
|
-
# end
|
18
|
-
# @!macro [new] throttle.example.throttled_future_chain
|
19
|
-
# @example
|
20
|
-
# throttle.throttled_future_chain do |trigger|
|
21
|
-
# trigger.
|
22
|
-
# # 2 throttled promises
|
23
|
-
# chain { 1 }.
|
24
|
-
# then(&:succ)
|
25
|
-
# end
|
26
|
-
# @!macro [new] throttle.example.then_throttled_by
|
27
|
-
# @example
|
28
|
-
# data = (1..5).to_a
|
29
|
-
# db = data.reduce({}) { |h, v| h.update v => v.to_s }
|
30
|
-
# max_two = Throttle.new 2
|
31
|
-
#
|
32
|
-
# futures = data.map do |data|
|
33
|
-
# Promises.future(data) do |data|
|
34
|
-
# # un-throttled, concurrency level equal data.size
|
35
|
-
# data + 1
|
36
|
-
# end.then_throttled_by(max_two, db) do |v, db|
|
37
|
-
# # throttled, only 2 tasks executed at the same time
|
38
|
-
# # e.g. limiting access to db
|
39
|
-
# db[v]
|
40
|
-
# end
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# futures.map(&:value!) # => [2, 3, 4, 5, nil]
|
44
|
-
|
45
|
-
# A tool manage concurrency level of future tasks.
|
46
|
-
#
|
47
|
-
# @!macro throttle.example.then_throttled_by
|
48
|
-
# @!macro throttle.example.throttled_future
|
49
|
-
# @!macro throttle.example.throttled_future_chain
|
50
|
-
# @!macro throttle.example.throttled_block
|
51
|
-
class Throttle < Synchronization::Object
|
52
|
-
# TODO (pitr-ch 21-Dec-2016): consider using sized channel for implementation instead when available
|
53
|
-
|
54
|
-
safe_initialization!
|
55
|
-
private *attr_atomic(:can_run)
|
56
|
-
|
57
|
-
# New throttle.
|
58
|
-
# @param [Integer] limit
|
59
|
-
def initialize(limit)
|
60
|
-
super()
|
61
|
-
@Limit = limit
|
62
|
-
self.can_run = limit
|
63
|
-
@Queue = LockFreeQueue.new
|
64
|
-
end
|
65
|
-
|
66
|
-
# @return [Integer] The limit.
|
67
|
-
def limit
|
68
|
-
@Limit
|
69
|
-
end
|
70
|
-
|
71
|
-
# New event which will be resolved when depending tasks can execute.
|
72
|
-
# Has to be used and after the critical work is done {#release} must be called exactly once.
|
73
|
-
# @return [Promises::Event]
|
74
|
-
# @see #release
|
75
|
-
def trigger
|
76
|
-
while true
|
77
|
-
current_can_run = can_run
|
78
|
-
if compare_and_set_can_run current_can_run, current_can_run - 1
|
79
|
-
if current_can_run > 0
|
80
|
-
return Promises.resolved_event
|
81
|
-
else
|
82
|
-
event = Promises.resolvable_event
|
83
|
-
@Queue.push event
|
84
|
-
return event
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# Has to be called once for each trigger after it is ok to execute another throttled task.
|
91
|
-
# @return [self]
|
92
|
-
# @see #trigger
|
93
|
-
def release
|
94
|
-
while true
|
95
|
-
current_can_run = can_run
|
96
|
-
if compare_and_set_can_run current_can_run, current_can_run + 1
|
97
|
-
if current_can_run < 0
|
98
|
-
Thread.pass until (trigger = @Queue.pop)
|
99
|
-
trigger.resolve
|
100
|
-
end
|
101
|
-
return self
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# Blocks current thread until the block can be executed.
|
107
|
-
# @yield to throttled block
|
108
|
-
# @yieldreturn [Object] is used as a result of the method
|
109
|
-
# @return [Object] the result of the block
|
110
|
-
# @!macro throttle.example.throttled_block
|
111
|
-
def throttled_block(&block)
|
112
|
-
trigger.wait
|
113
|
-
block.call
|
114
|
-
ensure
|
115
|
-
release
|
116
|
-
end
|
117
|
-
|
118
|
-
# @return [String] Short string representation.
|
119
|
-
def to_s
|
120
|
-
format '<#%s:0x%x limit:%s can_run:%d>', self.class, object_id << 1, @Limit, can_run
|
121
|
-
end
|
122
|
-
|
123
|
-
alias_method :inspect, :to_s
|
124
|
-
|
125
|
-
module PromisesIntegration
|
126
|
-
|
127
|
-
# Allows to throttle a chain of promises.
|
128
|
-
# @yield [trigger] a trigger which has to be used to build up a chain of promises, the last one is result
|
129
|
-
# of the block. When the last one resolves, {Throttle#release} is called on the throttle.
|
130
|
-
# @yieldparam [Promises::Event, Promises::Future] trigger
|
131
|
-
# @yieldreturn [Promises::Event, Promises::Future] The final future of the throttled chain.
|
132
|
-
# @return [Promises::Event, Promises::Future] The final future of the throttled chain.
|
133
|
-
# @!macro throttle.example.throttled_future_chain
|
134
|
-
def throttled_future_chain(&throttled_futures)
|
135
|
-
throttled_futures.call(trigger).on_resolution! { release }
|
136
|
-
end
|
137
|
-
|
138
|
-
# Behaves as {Promises::FactoryMethods#future} but the future is throttled.
|
139
|
-
# @return [Promises::Future]
|
140
|
-
# @see Promises::FactoryMethods#future
|
141
|
-
# @!macro throttle.example.throttled_future
|
142
|
-
def throttled_future(*args, &task)
|
143
|
-
trigger.chain(*args, &task).on_resolution! { release }
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
include PromisesIntegration
|
148
|
-
end
|
149
|
-
|
150
|
-
module Promises
|
151
|
-
|
152
|
-
class AbstractEventFuture < Synchronization::Object
|
153
|
-
module ThrottleIntegration
|
154
|
-
def throttled_by(throttle, &throttled_futures)
|
155
|
-
a_trigger = self & self.chain { throttle.trigger }.flat_event
|
156
|
-
throttled_futures.call(a_trigger).on_resolution! { throttle.release }
|
157
|
-
end
|
158
|
-
|
159
|
-
# Behaves as {Promises::AbstractEventFuture#chain} but the it is throttled.
|
160
|
-
# @return [Promises::Future, Promises::Event]
|
161
|
-
# @see Promises::AbstractEventFuture#chain
|
162
|
-
def chain_throttled_by(throttle, *args, &block)
|
163
|
-
throttled_by(throttle) { |trigger| trigger.chain(*args, &block) }
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
include ThrottleIntegration
|
168
|
-
end
|
169
|
-
|
170
|
-
class Future < AbstractEventFuture
|
171
|
-
module ThrottleIntegration
|
172
|
-
|
173
|
-
# Behaves as {Promises::Future#then} but the it is throttled.
|
174
|
-
# @return [Promises::Future]
|
175
|
-
# @see Promises::Future#then
|
176
|
-
# @!macro throttle.example.then_throttled_by
|
177
|
-
def then_throttled_by(throttle, *args, &block)
|
178
|
-
throttled_by(throttle) { |trigger| trigger.then(*args, &block) }
|
179
|
-
end
|
180
|
-
|
181
|
-
# Behaves as {Promises::Future#rescue} but the it is throttled.
|
182
|
-
# @return [Promises::Future]
|
183
|
-
# @see Promises::Future#rescue
|
184
|
-
def rescue_throttled_by(throttle, *args, &block)
|
185
|
-
throttled_by(throttle) { |trigger| trigger.rescue(*args, &block) }
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
include ThrottleIntegration
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
/data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/lock_free_linked_set/window.rb
RENAMED
File without changes
|