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.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +552 -0
  3. data/LICENSE.txt +18 -18
  4. data/README.md +261 -103
  5. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/abstract.rb +2 -0
  6. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/awaits.rb +2 -0
  7. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/buffer.rb +2 -0
  8. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/errors_on_unknown_message.rb +2 -0
  9. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/executes_context.rb +2 -0
  10. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/linking.rb +2 -0
  11. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/pausing.rb +2 -0
  12. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/removes_child.rb +2 -0
  13. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/sets_results.rb +2 -0
  14. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/supervising.rb +2 -0
  15. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour/termination.rb +3 -1
  16. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/behaviour.rb +1 -1
  17. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/context.rb +3 -1
  18. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/core.rb +5 -4
  19. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/default_dead_letter_handler.rb +2 -0
  20. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/envelope.rb +2 -0
  21. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/errors.rb +2 -0
  22. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/internal_delegations.rb +3 -0
  23. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/reference.rb +9 -8
  24. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/root.rb +3 -0
  25. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils/ad_hoc.rb +2 -0
  26. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils/balancer.rb +2 -0
  27. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils/broadcast.rb +1 -0
  28. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils/pool.rb +1 -0
  29. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor.rb +11 -6
  30. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/base.rb +14 -14
  31. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/dropping.rb +1 -0
  32. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/sliding.rb +1 -0
  33. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/unbuffered.rb +1 -1
  34. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/tick.rb +1 -1
  35. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel.rb +3 -2
  36. data/lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb +107 -0
  37. data/lib/concurrent-ruby-edge/concurrent/edge/channel.rb +453 -0
  38. data/lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb +1549 -0
  39. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/lock_free_linked_set/node.rb +2 -2
  40. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/lock_free_linked_set.rb +8 -7
  41. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/lock_free_queue.rb +2 -0
  42. data/lib/{concurrent → concurrent-ruby-edge/concurrent}/edge/old_channel_integration.rb +2 -0
  43. data/lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb +184 -0
  44. data/lib/concurrent-ruby-edge/concurrent/edge/promises.rb +174 -0
  45. data/lib/concurrent-ruby-edge/concurrent/edge/throttle.rb +229 -0
  46. data/lib/concurrent-ruby-edge/concurrent/edge/version.rb +3 -0
  47. data/lib/concurrent-ruby-edge/concurrent/edge.rb +21 -0
  48. data/lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb +50 -0
  49. data/lib/concurrent-ruby-edge/concurrent/lazy_register.rb +83 -0
  50. data/lib/{concurrent-edge.rb → concurrent-ruby-edge/concurrent-edge.rb} +5 -4
  51. metadata +71 -67
  52. data/lib/concurrent/edge/atomic_markable_reference.rb +0 -184
  53. data/lib/concurrent/edge/cancellation.rb +0 -138
  54. data/lib/concurrent/edge/lock_free_stack.rb +0 -126
  55. data/lib/concurrent/edge/processing_actor.rb +0 -161
  56. data/lib/concurrent/edge/promises.rb +0 -2111
  57. data/lib/concurrent/edge/throttle.rb +0 -192
  58. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/public_delegations.rb +0 -0
  59. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/type_check.rb +0 -0
  60. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/actor/utils.rb +0 -0
  61. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/buffered.rb +0 -0
  62. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/ticker.rb +0 -0
  63. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer/timer.rb +0 -0
  64. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/buffer.rb +0 -0
  65. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/after_clause.rb +0 -0
  66. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/default_clause.rb +0 -0
  67. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/error_clause.rb +0 -0
  68. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/put_clause.rb +0 -0
  69. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector/take_clause.rb +0 -0
  70. /data/lib/{concurrent → concurrent-ruby-edge/concurrent}/channel/selector.rb +0 -0
  71. /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