async 2.5.1 → 2.6.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/node.rb +15 -6
- data/lib/async/scheduler.rb +12 -1
- data/lib/async/task.rb +46 -6
- data/lib/async/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +17 -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: 0f62c8150ba7dba6f26532b080a4c99ecde97d86cf5f31746aec706d12644550
|
4
|
+
data.tar.gz: 99bbe4f65da2c18ab75bc67377896b7b6c26f6056eb789ef22d5601f43526228
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c6a7fee5fb6d429b7533afb80dd38ad499c8dd313ee5f881cdd19479a8f1f28072f16f07f83305f6d2e6ddaa7907859938fcd69e2fc7b0e945b194588fd22e2
|
7
|
+
data.tar.gz: f10a739ba6013c928199c4abe884e9dbf9d4d48d7f8329ed3977bb9230584d100505d617a859c113bf04c25cbf9ae4353e525221563f930227467cbaebf153b1
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/async/node.rb
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
# Copyright, 2017, by Kent Gruber.
|
6
6
|
# Copyright, 2022, by Shannon Skipper.
|
7
7
|
|
8
|
+
require 'fiber/annotation'
|
9
|
+
|
8
10
|
require_relative 'list'
|
9
11
|
|
10
12
|
module Async
|
@@ -109,20 +111,27 @@ module Async
|
|
109
111
|
|
110
112
|
def annotate(annotation)
|
111
113
|
if block_given?
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
114
|
+
begin
|
115
|
+
current_annotation = @annotation
|
116
|
+
@annotation = annotation
|
117
|
+
return yield
|
118
|
+
ensure
|
119
|
+
@annotation = current_annotation
|
120
|
+
end
|
116
121
|
else
|
117
122
|
@annotation = annotation
|
118
123
|
end
|
119
124
|
end
|
120
125
|
|
126
|
+
def annotation
|
127
|
+
@annotation
|
128
|
+
end
|
129
|
+
|
121
130
|
def description
|
122
131
|
@object_name ||= "#{self.class}:#{format '%#018x', object_id}#{@transient ? ' transient' : nil}"
|
123
132
|
|
124
|
-
if
|
125
|
-
"#{@object_name} #{
|
133
|
+
if annotation = self.annotation
|
134
|
+
"#{@object_name} #{annotation}"
|
126
135
|
elsif line = self.backtrace(0, 1)&.first
|
127
136
|
"#{@object_name} #{line}"
|
128
137
|
else
|
data/lib/async/scheduler.rb
CHANGED
@@ -17,6 +17,12 @@ require 'resolv'
|
|
17
17
|
module Async
|
18
18
|
# Handles scheduling of fibers. Implements the fiber scheduler interface.
|
19
19
|
class Scheduler < Node
|
20
|
+
class ClosedError < RuntimeError
|
21
|
+
def initialize(message = "Scheduler is closed!")
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
20
26
|
# Whether the fiber scheduler is supported.
|
21
27
|
# @public Since `stable-v1`.
|
22
28
|
def self.supported?
|
@@ -150,6 +156,9 @@ module Async
|
|
150
156
|
|
151
157
|
# @asynchronous May be non-blocking..
|
152
158
|
def address_resolve(hostname)
|
159
|
+
# On some platforms, hostnames may contain a device-specific suffix (e.g. %en0). We need to strip this before resolving.
|
160
|
+
# See <https://github.com/socketry/async/issues/180> for more details.
|
161
|
+
hostname = hostname.split("%", 2).first
|
153
162
|
::Resolv.getaddresses(hostname)
|
154
163
|
end
|
155
164
|
|
@@ -233,7 +242,7 @@ module Async
|
|
233
242
|
|
234
243
|
# Run the reactor until all tasks are finished. Proxies arguments to {#async} immediately before entering the loop, if a block is provided.
|
235
244
|
def run(...)
|
236
|
-
Kernel::raise
|
245
|
+
Kernel::raise ClosedError if @selector.nil?
|
237
246
|
|
238
247
|
initial_task = self.async(...) if block_given?
|
239
248
|
|
@@ -260,6 +269,8 @@ module Async
|
|
260
269
|
# @returns [Task] The task that was scheduled into the reactor.
|
261
270
|
# @deprecated With no replacement.
|
262
271
|
def async(*arguments, **options, &block)
|
272
|
+
Kernel::raise ClosedError if @selector.nil?
|
273
|
+
|
263
274
|
task = Task.new(Task.current? || self, **options, &block)
|
264
275
|
|
265
276
|
# I want to take a moment to explain the logic of this.
|
data/lib/async/task.rb
CHANGED
@@ -59,6 +59,12 @@ module Async
|
|
59
59
|
#
|
60
60
|
# @public Since `stable-v1`.
|
61
61
|
class Task < Node
|
62
|
+
class FinishedError < RuntimeError
|
63
|
+
def initialize(message = "Cannot create child task within a task that has finished execution!")
|
64
|
+
super
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
62
68
|
# @deprecated With no replacement.
|
63
69
|
def self.yield
|
64
70
|
Fiber.scheduler.transfer
|
@@ -90,6 +96,22 @@ module Async
|
|
90
96
|
@fiber&.backtrace(*arguments)
|
91
97
|
end
|
92
98
|
|
99
|
+
def annotate(annotation, &block)
|
100
|
+
if @fiber
|
101
|
+
@fiber.annotate(annotation, &block)
|
102
|
+
else
|
103
|
+
super
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def annotation
|
108
|
+
if @fiber
|
109
|
+
@fiber.annotation
|
110
|
+
else
|
111
|
+
super
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
93
115
|
def to_s
|
94
116
|
"\#<#{self.description} (#{@status})>"
|
95
117
|
end
|
@@ -164,7 +186,7 @@ module Async
|
|
164
186
|
|
165
187
|
# Run an asynchronous task as a child of the current task.
|
166
188
|
def async(*arguments, **options, &block)
|
167
|
-
raise
|
189
|
+
raise FinishedError if self.finished?
|
168
190
|
|
169
191
|
task = Task.new(self, **options, &block)
|
170
192
|
|
@@ -199,6 +221,10 @@ module Async
|
|
199
221
|
attr :result
|
200
222
|
|
201
223
|
# Stop the task and all of its children.
|
224
|
+
#
|
225
|
+
# If `later` is false, it means that `stop` has been invoked directly. When `later` is true, it means that `stop` is invoked by `stop_children` or some other indirect mechanism. In that case, if we encounter the "current" fiber, we can't stop it right away, as it's currently performing `#stop`. Stopping it immediately would interrupt the current stop traversal, so we need to schedule the stop to occur later.
|
226
|
+
#
|
227
|
+
# @parameter later [Boolean] Whether to stop the task later, or immediately.
|
202
228
|
def stop(later = false)
|
203
229
|
if self.stopped?
|
204
230
|
# If we already stopped this task... don't try to stop it again:
|
@@ -208,6 +234,7 @@ module Async
|
|
208
234
|
# If the fiber is alive, we need to stop it:
|
209
235
|
if @fiber&.alive?
|
210
236
|
if self.current?
|
237
|
+
# If the fiber is current, and later is `true`, we need to schedule the fiber to be stopped later, as it's currently invoking `stop`:
|
211
238
|
if later
|
212
239
|
# If the fiber is the current fiber and we want to stop it later, schedule it:
|
213
240
|
Fiber.scheduler.push(Stop::Later.new(self))
|
@@ -218,6 +245,7 @@ module Async
|
|
218
245
|
else
|
219
246
|
# If the fiber is not curent, we can raise the exception directly:
|
220
247
|
begin
|
248
|
+
# There is a chance that this will stop the fiber that originally called stop. If that happens, the exception handling in `#stopped` will rescue the exception and re-raise it later.
|
221
249
|
Fiber.scheduler.raise(@fiber, Stop)
|
222
250
|
rescue FiberError
|
223
251
|
# In some cases, this can cause a FiberError (it might be resumed already), so we schedule it to be stopped later:
|
@@ -244,7 +272,7 @@ module Async
|
|
244
272
|
end
|
245
273
|
|
246
274
|
def current?
|
247
|
-
|
275
|
+
Fiber.current.equal?(@fiber)
|
248
276
|
end
|
249
277
|
|
250
278
|
private
|
@@ -289,11 +317,23 @@ module Async
|
|
289
317
|
end
|
290
318
|
|
291
319
|
def stopped!
|
292
|
-
# Console.logger.info(self,
|
320
|
+
# Console.logger.info(self, status:) {"Task #{self} was stopped with #{@children&.size.inspect} children!"}
|
293
321
|
@status = :stopped
|
294
322
|
|
295
|
-
|
296
|
-
|
323
|
+
stopped = false
|
324
|
+
|
325
|
+
begin
|
326
|
+
# We are bnot running, but children might be so we should stop them:
|
327
|
+
stop_children(true)
|
328
|
+
rescue Stop
|
329
|
+
stopped = true
|
330
|
+
# If we are stopping children, and one of them tries to stop the current task, we should ignore it. We will be stopped later.
|
331
|
+
retry
|
332
|
+
end
|
333
|
+
|
334
|
+
if stopped
|
335
|
+
raise Stop, "Stopping current task!"
|
336
|
+
end
|
297
337
|
end
|
298
338
|
|
299
339
|
def stop!
|
@@ -303,7 +343,7 @@ module Async
|
|
303
343
|
end
|
304
344
|
|
305
345
|
def schedule(&block)
|
306
|
-
@fiber = Fiber.new do
|
346
|
+
@fiber = Fiber.new(annotation: self.annotation) do
|
307
347
|
set!
|
308
348
|
|
309
349
|
begin
|
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.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -56,7 +56,7 @@ cert_chain:
|
|
56
56
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
57
57
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
58
58
|
-----END CERTIFICATE-----
|
59
|
-
date: 2023-
|
59
|
+
date: 2023-06-07 00:00:00.000000000 Z
|
60
60
|
dependencies:
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: console
|
@@ -100,6 +100,20 @@ dependencies:
|
|
100
100
|
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '4.1'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: fiber-annotation
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :runtime
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
103
117
|
- !ruby/object:Gem::Dependency
|
104
118
|
name: bake-test
|
105
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -247,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
247
261
|
- !ruby/object:Gem::Version
|
248
262
|
version: '0'
|
249
263
|
requirements: []
|
250
|
-
rubygems_version: 3.
|
264
|
+
rubygems_version: 3.4.7
|
251
265
|
signing_key:
|
252
266
|
specification_version: 4
|
253
267
|
summary: A concurrency framework for Ruby.
|
metadata.gz.sig
CHANGED
Binary file
|