async 2.3.0 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/barrier.md +4 -2
- data/lib/async/list.rb +154 -27
- data/lib/async/node.rb +3 -4
- data/lib/async/task.rb +1 -1
- data/lib/async/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +3 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 042a45792628d56b89e02200e38d6d00fb16c5311b95c3dae7d52607aef8108a
|
4
|
+
data.tar.gz: 6e7b3271d484ee3aabe395996ca987b1e0043d6d8710b3b706688993df43c916
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49ea21f4f81b9e566119265b834ecbfb4de8db83788370e18d3d27b14e7a2ec972960f67301139dd61111f13843325264412bf096b5b33cafff910630b1663cb
|
7
|
+
data.tar.gz: 151eee11c70bf263c72cae52142168449ba38cd68a00ad302c2c9fcf53088de65784f35193971628e6c1ddb9d7efab9677359040ed19e13cde1f846670fd9b3e
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/async/barrier.md
CHANGED
@@ -7,6 +7,7 @@ require 'async'
|
|
7
7
|
require 'async/barrier'
|
8
8
|
|
9
9
|
Sync do
|
10
|
+
Console.logger.info("Barrier Example: sleep sort.")
|
10
11
|
barrier = Async::Barrier.new
|
11
12
|
|
12
13
|
# Generate an array of 10 numbers:
|
@@ -31,6 +32,7 @@ end
|
|
31
32
|
### Output
|
32
33
|
|
33
34
|
~~~
|
34
|
-
0.0s info:
|
35
|
-
|
35
|
+
0.0s info: Barrier Example: sleep sort.
|
36
|
+
9.0s info: Sorted
|
37
|
+
| [3, 3, 3, 4, 4, 5, 5, 5, 8, 9]
|
36
38
|
~~~
|
data/lib/async/list.rb
CHANGED
@@ -15,11 +15,27 @@ module Async
|
|
15
15
|
|
16
16
|
# Print a short summary of the list.
|
17
17
|
def to_s
|
18
|
-
"
|
18
|
+
sprintf("#<%s:0x%x size=%d>", self.class.name, object_id, @size)
|
19
19
|
end
|
20
20
|
|
21
21
|
alias inspect to_s
|
22
22
|
|
23
|
+
# Fast, safe, unbounded accumulation of children.
|
24
|
+
def to_a
|
25
|
+
items = []
|
26
|
+
current = self
|
27
|
+
|
28
|
+
while current.tail != self
|
29
|
+
unless current.tail.is_a?(Iterator)
|
30
|
+
items << current.tail
|
31
|
+
end
|
32
|
+
|
33
|
+
current = current.tail
|
34
|
+
end
|
35
|
+
|
36
|
+
return items
|
37
|
+
end
|
38
|
+
|
23
39
|
# Points at the end of the list.
|
24
40
|
attr_accessor :head
|
25
41
|
|
@@ -118,30 +134,46 @@ module Async
|
|
118
134
|
|
119
135
|
# @returns [Boolean] Returns true if the list is empty.
|
120
136
|
def empty?
|
121
|
-
@
|
137
|
+
@size == 0
|
122
138
|
end
|
123
139
|
|
140
|
+
# def validate!(node = nil)
|
141
|
+
# previous = self
|
142
|
+
# current = @tail
|
143
|
+
# found = node.equal?(self)
|
144
|
+
|
145
|
+
# while true
|
146
|
+
# break if current.equal?(self)
|
147
|
+
|
148
|
+
# if current.head != previous
|
149
|
+
# raise "Invalid previous linked list node!"
|
150
|
+
# end
|
151
|
+
|
152
|
+
# if current.is_a?(List) and !current.equal?(self)
|
153
|
+
# raise "Invalid list in list node!"
|
154
|
+
# end
|
155
|
+
|
156
|
+
# if node
|
157
|
+
# found ||= current.equal?(node)
|
158
|
+
# end
|
159
|
+
|
160
|
+
# previous = current
|
161
|
+
# current = current.tail
|
162
|
+
# end
|
163
|
+
|
164
|
+
# if node and !found
|
165
|
+
# raise "Node not found in list!"
|
166
|
+
# end
|
167
|
+
# end
|
168
|
+
|
124
169
|
# Iterate over each node in the linked list. It is generally safe to remove the current node, any previous node or any future node during iteration.
|
125
170
|
#
|
126
171
|
# @yields {|node| ...} Yields each node in the list.
|
127
172
|
# @returns [List] Returns self.
|
128
|
-
def each
|
173
|
+
def each(&block)
|
129
174
|
return to_enum unless block_given?
|
130
175
|
|
131
|
-
|
132
|
-
|
133
|
-
while true
|
134
|
-
node = current.tail
|
135
|
-
# binding.irb if node.nil? && !node.equal?(self)
|
136
|
-
break if node.equal?(self)
|
137
|
-
|
138
|
-
yield node
|
139
|
-
|
140
|
-
# If the node has deleted itself or any subsequent node, it will no longer be the next node, so don't use it for continued traversal:
|
141
|
-
if current.tail.equal?(node)
|
142
|
-
current = node
|
143
|
-
end
|
144
|
-
end
|
176
|
+
Iterator.each(self, &block)
|
145
177
|
|
146
178
|
return self
|
147
179
|
end
|
@@ -160,22 +192,117 @@ module Async
|
|
160
192
|
|
161
193
|
# @returns [Node] Returns the first node in the list, if it is not empty.
|
162
194
|
def first
|
163
|
-
|
164
|
-
|
195
|
+
# validate!
|
196
|
+
|
197
|
+
current = @tail
|
198
|
+
|
199
|
+
while !current.equal?(self)
|
200
|
+
if current.is_a?(Iterator)
|
201
|
+
current = current.tail
|
202
|
+
else
|
203
|
+
return current
|
204
|
+
end
|
165
205
|
end
|
206
|
+
|
207
|
+
return nil
|
166
208
|
end
|
167
209
|
|
168
210
|
# @returns [Node] Returns the last node in the list, if it is not empty.
|
169
211
|
def last
|
170
|
-
|
171
|
-
|
212
|
+
# validate!
|
213
|
+
|
214
|
+
current = @head
|
215
|
+
|
216
|
+
while !current.equal?(self)
|
217
|
+
if current.is_a?(Iterator)
|
218
|
+
current = current.head
|
219
|
+
else
|
220
|
+
return current
|
221
|
+
end
|
172
222
|
end
|
223
|
+
|
224
|
+
return nil
|
173
225
|
end
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
226
|
+
|
227
|
+
def shift
|
228
|
+
if node = first
|
229
|
+
remove!(node)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# A linked list Node.
|
234
|
+
class Node
|
235
|
+
attr_accessor :head
|
236
|
+
attr_accessor :tail
|
237
|
+
|
238
|
+
alias inspect to_s
|
239
|
+
end
|
240
|
+
|
241
|
+
class Iterator < Node
|
242
|
+
def initialize(list)
|
243
|
+
@list = list
|
244
|
+
|
245
|
+
# Insert the iterator as the first item in the list:
|
246
|
+
@tail = list.tail
|
247
|
+
@tail.head = self
|
248
|
+
list.tail = self
|
249
|
+
@head = list
|
250
|
+
end
|
251
|
+
|
252
|
+
def remove!
|
253
|
+
@head.tail = @tail
|
254
|
+
@tail.head = @head
|
255
|
+
@head = nil
|
256
|
+
@tail = nil
|
257
|
+
@list = nil
|
258
|
+
end
|
259
|
+
|
260
|
+
def move_next
|
261
|
+
# Move to the next item (which could be an iterator or the end):
|
262
|
+
@tail.head = @head
|
263
|
+
@head.tail = @tail
|
264
|
+
@head = @tail
|
265
|
+
@tail = @tail.tail
|
266
|
+
@head.tail = self
|
267
|
+
@tail.head = self
|
268
|
+
end
|
269
|
+
|
270
|
+
def move_current
|
271
|
+
while true
|
272
|
+
# Are we at the end of the list?
|
273
|
+
if @tail.equal?(@list)
|
274
|
+
return nil
|
275
|
+
end
|
276
|
+
|
277
|
+
if @tail.is_a?(Iterator)
|
278
|
+
move_next
|
279
|
+
else
|
280
|
+
return @tail
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def each
|
286
|
+
while current = move_current
|
287
|
+
yield current
|
288
|
+
|
289
|
+
if current.equal?(@tail)
|
290
|
+
move_next
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def self.each(list, &block)
|
296
|
+
return if list.empty?
|
297
|
+
|
298
|
+
iterator = Iterator.new(list)
|
299
|
+
|
300
|
+
iterator.each(&block)
|
301
|
+
ensure
|
302
|
+
iterator&.remove!
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
private_constant :Iterator
|
180
307
|
end
|
181
308
|
end
|
data/lib/async/node.rb
CHANGED
@@ -187,13 +187,12 @@ module Async
|
|
187
187
|
if parent = @parent and finished?
|
188
188
|
parent.remove_child(self)
|
189
189
|
|
190
|
+
# If we have children, then we need to move them to our the parent if they are not finished:
|
190
191
|
if @children
|
191
|
-
@children.
|
192
|
+
while child = @children.shift
|
192
193
|
if child.finished?
|
193
|
-
|
194
|
+
child.set_parent(nil)
|
194
195
|
else
|
195
|
-
# In theory we don't need to do this... because we are throwing away the list. However, if you don't correctly update the list when moving the child to the parent, it foobars the enumeration, and subsequent nodes will be skipped, or in the worst case you might start enumerating the parents nodes.
|
196
|
-
remove_child(child)
|
197
196
|
parent.add_child(child)
|
198
197
|
end
|
199
198
|
end
|
data/lib/async/task.rb
CHANGED
@@ -263,7 +263,7 @@ module Async
|
|
263
263
|
self.root.resume(@fiber)
|
264
264
|
end
|
265
265
|
|
266
|
-
# Finish the current task,
|
266
|
+
# Finish the current task, moving any children to the parent.
|
267
267
|
def finish!
|
268
268
|
# Allow the fiber to be recycled.
|
269
269
|
@fiber = nil
|
data/lib/async/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -54,7 +54,7 @@ cert_chain:
|
|
54
54
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
55
55
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
56
56
|
-----END CERTIFICATE-----
|
57
|
-
date: 2022-12-
|
57
|
+
date: 2022-12-28 00:00:00.000000000 Z
|
58
58
|
dependencies:
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: console
|
@@ -259,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
259
259
|
- !ruby/object:Gem::Version
|
260
260
|
version: '0'
|
261
261
|
requirements: []
|
262
|
-
rubygems_version: 3.
|
262
|
+
rubygems_version: 3.4.1
|
263
263
|
signing_key:
|
264
264
|
specification_version: 4
|
265
265
|
summary: A concurrency framework for Ruby.
|
metadata.gz.sig
CHANGED
Binary file
|