async 2.17.0 → 2.19.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 +2 -2
- data/lib/async/barrier.rb +3 -3
- data/lib/async/condition.rb +2 -2
- data/lib/async/console.rb +37 -0
- data/lib/async/node.rb +2 -2
- data/lib/async/notification.rb +1 -1
- data/lib/async/queue.rb +2 -2
- data/lib/async/reactor.rb +1 -1
- data/lib/async/scheduler.rb +13 -6
- data/lib/async/semaphore.rb +2 -2
- data/lib/async/task.rb +5 -7
- data/lib/async/variable.rb +1 -1
- data/lib/async/version.rb +1 -1
- data/lib/kernel/sync.rb +8 -3
- data/readme.md +11 -0
- data/releases.md +47 -0
- data.tar.gz.sig +0 -0
- metadata +7 -6
- 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: f095de1e8131ef68c86aeb0176f159d529614e0cc4550e09942c740602e5684c
|
4
|
+
data.tar.gz: 110037688f349d660617df61c86bd637c367a7f0bde68a1920aaac6c508b9de4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d287fb690ce18f7b75df003cc7f8a93752c347dc7c0dbcdfcd23fa42827368f228ffcb867482e69f94df87fb140b7bcf0da4ca666692504b1221052dd8c6f6ec
|
7
|
+
data.tar.gz: 8689282009332c05d4e6a958d1e612c77316f2e6084979b2201f073d5afc8e2d05e778d814f35de1a5c83f33c29e08221ca124c4367811f1bc5d92820de61e6b
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
��
|
1
|
+
~ ��zv G���d7���U']XF��ZE�+l�U�:
|
2
|
+
?�(���t��>�oPlKOf�終qO����ݏ��|�u�i�vCT�ЬP�Z��WjH/�璐k��N�F����7���I)��T{�8�=��ȳژ�{Z6�1�G����Q`C�"�zrÛ[e�Pep�
|
data/lib/async/barrier.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
6
|
+
require_relative "list"
|
7
|
+
require_relative "task"
|
8
8
|
|
9
9
|
module Async
|
10
10
|
# A general purpose synchronisation primitive, which allows one task to wait for a number of other tasks to complete. It can be used in conjunction with {Semaphore}.
|
data/lib/async/condition.rb
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
# Copyright, 2017-2024, by Samuel Williams.
|
5
5
|
# Copyright, 2017, by Kent Gruber.
|
6
6
|
|
7
|
-
require
|
8
|
-
require_relative
|
7
|
+
require "fiber"
|
8
|
+
require_relative "list"
|
9
9
|
|
10
10
|
module Async
|
11
11
|
# A synchronization primitive, which allows fibers to wait until a particular condition is (edge) triggered.
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2024, by Samuel Williams.
|
5
|
+
|
6
|
+
module Async
|
7
|
+
# Shims for the console gem, redirecting warnings and above to `Kernel#warn`.
|
8
|
+
#
|
9
|
+
# If you require this file, the `async` library will not depend on the `console` gem.
|
10
|
+
#
|
11
|
+
# That includes any gems that sit within the `Async` namespace.
|
12
|
+
#
|
13
|
+
# This is an experimental feature.
|
14
|
+
module Console
|
15
|
+
def self.debug(...)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.info(...)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.warn(*arguments, exception: nil, **options)
|
22
|
+
if exception
|
23
|
+
super(*arguments, exception.full_message, **options)
|
24
|
+
else
|
25
|
+
super(*arguments, **options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.error(...)
|
30
|
+
self.warn(...)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.fatal(...)
|
34
|
+
self.warn(...)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/async/node.rb
CHANGED
data/lib/async/notification.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "condition"
|
7
7
|
|
8
8
|
module Async
|
9
9
|
# A synchronization primitive, which allows fibers to wait until a notification is received. Does not block the task which signals the notification. Waiting tasks are resumed on next iteration of the reactor.
|
data/lib/async/queue.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Copyright, 2019, by Ryan Musgrave.
|
6
6
|
# Copyright, 2020-2022, by Bruno Sutic.
|
7
7
|
|
8
|
-
require_relative
|
8
|
+
require_relative "notification"
|
9
9
|
|
10
10
|
module Async
|
11
11
|
# A queue which allows items to be processed in order.
|
@@ -88,7 +88,7 @@ module Async
|
|
88
88
|
end
|
89
89
|
|
90
90
|
# Signal the queue with a value, the same as {#enqueue}.
|
91
|
-
def signal(value)
|
91
|
+
def signal(value = nil)
|
92
92
|
self.enqueue(value)
|
93
93
|
end
|
94
94
|
|
data/lib/async/reactor.rb
CHANGED
data/lib/async/scheduler.rb
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
# Copyright, 2020, by Jun Jiang.
|
6
6
|
# Copyright, 2021, by Julien Portalier.
|
7
7
|
|
8
|
-
require_relative
|
9
|
-
require_relative
|
8
|
+
require_relative "clock"
|
9
|
+
require_relative "task"
|
10
10
|
|
11
|
-
require
|
11
|
+
require "io/event"
|
12
12
|
|
13
|
-
require
|
14
|
-
require
|
13
|
+
require "console"
|
14
|
+
require "resolv"
|
15
15
|
|
16
16
|
module Async
|
17
17
|
# Handles scheduling of fibers. Implements the fiber scheduler interface.
|
@@ -388,6 +388,11 @@ module Async
|
|
388
388
|
end
|
389
389
|
rescue Interrupt => interrupt
|
390
390
|
Thread.handle_interrupt(::SignalException => :never) do
|
391
|
+
Console.debug(self) do |buffer|
|
392
|
+
buffer.puts "Scheduler interrupted: #{interrupt.inspect}"
|
393
|
+
self.print_hierarchy(buffer)
|
394
|
+
end
|
395
|
+
|
391
396
|
self.stop
|
392
397
|
end
|
393
398
|
|
@@ -395,7 +400,9 @@ module Async
|
|
395
400
|
end
|
396
401
|
|
397
402
|
# If the event loop was interrupted, and we finished exiting normally (due to the interrupt), we need to re-raise the interrupt so that the caller can handle it too.
|
398
|
-
|
403
|
+
if interrupt
|
404
|
+
Kernel.raise(interrupt)
|
405
|
+
end
|
399
406
|
end
|
400
407
|
|
401
408
|
# Run the reactor until all tasks are finished. Proxies arguments to {#async} immediately before entering the loop, if a block is provided.
|
data/lib/async/semaphore.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2018-
|
4
|
+
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "list"
|
7
7
|
|
8
8
|
module Async
|
9
9
|
# A synchronization primitive, which limits access to a given resource.
|
data/lib/async/task.rb
CHANGED
@@ -7,11 +7,11 @@
|
|
7
7
|
# Copyright, 2020, by Patrik Wenger.
|
8
8
|
# Copyright, 2023, by Math Ieu.
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
10
|
+
require "fiber"
|
11
|
+
require "console"
|
12
12
|
|
13
|
-
require_relative
|
14
|
-
require_relative
|
13
|
+
require_relative "node"
|
14
|
+
require_relative "condition"
|
15
15
|
|
16
16
|
Fiber.attr_accessor :async_task
|
17
17
|
|
@@ -198,9 +198,7 @@ module Async
|
|
198
198
|
rescue => error
|
199
199
|
# I'm not completely happy with this overhead, but the alternative is to not log anything which makes debugging extremely difficult. Maybe we can introduce a debug wrapper which adds extra logging.
|
200
200
|
if @finished.nil?
|
201
|
-
Console
|
202
|
-
else
|
203
|
-
# Console::Event::Failure.for(error).emit(self, severity: :debug)
|
201
|
+
Console.warn(self, "Task may have ended with unhandled exception.", exception: error)
|
204
202
|
end
|
205
203
|
|
206
204
|
raise
|
data/lib/async/variable.rb
CHANGED
data/lib/async/version.rb
CHANGED
data/lib/kernel/sync.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
# Copyright, 2020, by Brian Morearty.
|
6
|
+
# Copyright, 2024, by Patrik Wenger.
|
6
7
|
|
7
8
|
require_relative "../async/reactor"
|
8
9
|
|
@@ -15,9 +16,13 @@ module Kernel
|
|
15
16
|
#
|
16
17
|
# @public Since `stable-v1`.
|
17
18
|
# @asynchronous Will block until given block completes executing.
|
18
|
-
def Sync(&block)
|
19
|
+
def Sync(annotation: nil, &block)
|
19
20
|
if task = ::Async::Task.current?
|
20
|
-
|
21
|
+
if annotation
|
22
|
+
task.annotate(annotation) {yield task}
|
23
|
+
else
|
24
|
+
yield task
|
25
|
+
end
|
21
26
|
elsif scheduler = Fiber.scheduler
|
22
27
|
::Async::Task.run(scheduler, &block).wait
|
23
28
|
else
|
@@ -25,7 +30,7 @@ module Kernel
|
|
25
30
|
reactor = Async::Reactor.new
|
26
31
|
|
27
32
|
begin
|
28
|
-
return reactor.run(finished: ::Async::Condition.new, &block).wait
|
33
|
+
return reactor.run(annotation: annotation, finished: ::Async::Condition.new, &block).wait
|
29
34
|
ensure
|
30
35
|
Fiber.set_scheduler(nil)
|
31
36
|
end
|
data/readme.md
CHANGED
@@ -35,8 +35,19 @@ Please see the [project documentation](https://socketry.github.io/async/) for mo
|
|
35
35
|
|
36
36
|
Please see the [project releases](https://socketry.github.io/async/releases/index) for all releases.
|
37
37
|
|
38
|
+
### v2.19.0
|
39
|
+
|
40
|
+
- [Async::Scheduler Debugging](https://socketry.github.io/async/releases/index#async::scheduler-debugging)
|
41
|
+
- [Console Shims](https://socketry.github.io/async/releases/index#console-shims)
|
42
|
+
|
43
|
+
### v2.18.0
|
44
|
+
|
45
|
+
- Add support for `Sync(annotation:)`, so that you can annotate the block with a description of what it does, even if it doesn't create a new task.
|
46
|
+
|
38
47
|
### v2.17.0
|
39
48
|
|
49
|
+
- Introduce `Async::Queue#push` and `Async::Queue#pop` for compatibility with `::Queue`.
|
50
|
+
|
40
51
|
### v2.16.0
|
41
52
|
|
42
53
|
- [Better Handling of Async and Sync in Nested Fibers](https://socketry.github.io/async/releases/index#better-handling-of-async-and-sync-in-nested-fibers)
|
data/releases.md
CHANGED
@@ -1,5 +1,52 @@
|
|
1
1
|
# Releases
|
2
2
|
|
3
|
+
## v2.19.0
|
4
|
+
|
5
|
+
### Async::Scheduler Debugging
|
6
|
+
|
7
|
+
Occasionally on issues, I encounter people asking for help and I need more information. Pressing Ctrl-C to exit a hung program is common, but it usually doesn't provide enough information to diagnose the problem. Setting the `CONSOLE_LEVEL=debug` environment variable will now print additional information about the scheduler when you interrupt it, including a backtrace of the current tasks.
|
8
|
+
|
9
|
+
> CONSOLE_LEVEL=debug bundle exec ruby ./test.rb
|
10
|
+
^C 0.0s debug: Async::Reactor [oid=0x974] [ec=0x988] [pid=9116] [2024-11-08 14:12:03 +1300]
|
11
|
+
| Scheduler interrupted: Interrupt
|
12
|
+
| #<Async::Reactor:0x0000000000000974 1 children (running)>
|
13
|
+
| #<Async::Task:0x000000000000099c /Users/samuel/Developer/socketry/async/lib/async/scheduler.rb:185:in `transfer' (running)>
|
14
|
+
| → /Users/samuel/Developer/socketry/async/lib/async/scheduler.rb:185:in `transfer'
|
15
|
+
| /Users/samuel/Developer/socketry/async/lib/async/scheduler.rb:185:in `block'
|
16
|
+
| /Users/samuel/Developer/socketry/async/lib/async/scheduler.rb:207:in `kernel_sleep'
|
17
|
+
| /Users/samuel/Developer/socketry/async/test.rb:7:in `sleep'
|
18
|
+
| /Users/samuel/Developer/socketry/async/test.rb:7:in `sleepy'
|
19
|
+
| /Users/samuel/Developer/socketry/async/test.rb:12:in `block in <top (required)>'
|
20
|
+
| /Users/samuel/Developer/socketry/async/lib/async/task.rb:197:in `block in run'
|
21
|
+
| /Users/samuel/Developer/socketry/async/lib/async/task.rb:420:in `block in schedule'
|
22
|
+
/Users/samuel/Developer/socketry/async/lib/async/scheduler.rb:317:in `select': Interrupt
|
23
|
+
... (backtrace continues) ...
|
24
|
+
|
25
|
+
This gives better visibility into what the scheduler is doing, and should help diagnose issues.
|
26
|
+
|
27
|
+
### Console Shims
|
28
|
+
|
29
|
+
The `async` gem depends on `console` gem, because my goal was to have good logging by default without thinking about it too much. However, some users prefer to avoid using the `console` gem for logging, so I've added an experimental set of shims which should allow you to bypass the `console` gem entirely.
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
require 'async/console'
|
33
|
+
require 'async'
|
34
|
+
|
35
|
+
Async{raise "Boom"}
|
36
|
+
```
|
37
|
+
|
38
|
+
Will now use `Kernel#warn` to print the task failure warning:
|
39
|
+
|
40
|
+
#<Async::Task:0x00000000000012d4 /home/samuel/Developer/socketry/async/lib/async/task.rb:104:in `backtrace' (running)>
|
41
|
+
Task may have ended with unhandled exception.
|
42
|
+
(irb):4:in `block in <top (required)>': Boom (RuntimeError)
|
43
|
+
from /home/samuel/Developer/socketry/async/lib/async/task.rb:197:in `block in run'
|
44
|
+
from /home/samuel/Developer/socketry/async/lib/async/task.rb:420:in `block in schedule'
|
45
|
+
|
46
|
+
## v2.18.0
|
47
|
+
|
48
|
+
- Add support for `Sync(annotation:)`, so that you can annotate the block with a description of what it does, even if it doesn't create a new task.
|
49
|
+
|
3
50
|
## v2.17.0
|
4
51
|
|
5
52
|
- Introduce `Async::Queue#push` and `Async::Queue#pop` for compatibility with `::Queue`.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
- Bruno Sutic
|
9
9
|
- Jeremy Jung
|
10
10
|
- Olle Jonsson
|
11
|
-
- Devin Christensen
|
12
11
|
- Patrik Wenger
|
12
|
+
- Devin Christensen
|
13
13
|
- Emil Tin
|
14
14
|
- Jamie McCarthy
|
15
15
|
- Kent Gruber
|
@@ -63,7 +63,7 @@ cert_chain:
|
|
63
63
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
64
64
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
65
65
|
-----END CERTIFICATE-----
|
66
|
-
date: 2024-
|
66
|
+
date: 2024-11-08 00:00:00.000000000 Z
|
67
67
|
dependencies:
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
69
|
name: console
|
@@ -71,14 +71,14 @@ dependencies:
|
|
71
71
|
requirements:
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '1.
|
74
|
+
version: '1.29'
|
75
75
|
type: :runtime
|
76
76
|
prerelease: false
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '1.
|
81
|
+
version: '1.29'
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: fiber-annotation
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- lib/async/clock.rb
|
126
126
|
- lib/async/condition.md
|
127
127
|
- lib/async/condition.rb
|
128
|
+
- lib/async/console.rb
|
128
129
|
- lib/async/idler.rb
|
129
130
|
- lib/async/list.rb
|
130
131
|
- lib/async/node.rb
|
@@ -161,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
161
162
|
requirements:
|
162
163
|
- - ">="
|
163
164
|
- !ruby/object:Gem::Version
|
164
|
-
version: 3.1
|
165
|
+
version: '3.1'
|
165
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
167
|
requirements:
|
167
168
|
- - ">="
|
metadata.gz.sig
CHANGED
Binary file
|