async 2.17.0 → 2.19.0
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 +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
|