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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a017a6f3304bf910379aeb0f16a40daa7fce7a3de0a3e56c97a359879a3910d1
4
- data.tar.gz: '09a048a8b24b6779d23540f85ba8e5a1d6317d9cfc87f91e74af22960a21fd29'
3
+ metadata.gz: f095de1e8131ef68c86aeb0176f159d529614e0cc4550e09942c740602e5684c
4
+ data.tar.gz: 110037688f349d660617df61c86bd637c367a7f0bde68a1920aaac6c508b9de4
5
5
  SHA512:
6
- metadata.gz: 415e7d9d23c06c60c752bb5b1ecbc336a98bd14b01b33c08bac56e4b8062b6b64761f4fcd8a412455705fb3908b715630beda5eaec7b62e3569e33cb37d235ea
7
- data.tar.gz: 8f31cdb2fa5aded62f174683f7a5c62589191bd9263fc9c1d07c78c319592d47f4d3eb46cf92ac0f3005dad219756d16961a6a93823564de1e0263c4f1e70cb3
6
+ metadata.gz: d287fb690ce18f7b75df003cc7f8a93752c347dc7c0dbcdfcd23fa42827368f228ffcb867482e69f94df87fb140b7bcf0da4ca666692504b1221052dd8c6f6ec
7
+ data.tar.gz: 8689282009332c05d4e6a958d1e612c77316f2e6084979b2201f073d5afc8e2d05e778d814f35de1a5c83f33c29e08221ca124c4367811f1bc5d92820de61e6b
checksums.yaml.gz.sig CHANGED
@@ -1,2 +1,2 @@
1
- Y�exuQ��h �� ��p��.\��Ѽ�Ѱ�@6��fL��b�o�+fo+*5>2e��bچ��2Jx� C0pw+w1��.�L�Ĭq#�E��{�����
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-2022, by Samuel Williams.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
5
 
6
- require_relative 'list'
7
- require_relative 'task'
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}.
@@ -4,8 +4,8 @@
4
4
  # Copyright, 2017-2024, by Samuel Williams.
5
5
  # Copyright, 2017, by Kent Gruber.
6
6
 
7
- require 'fiber'
8
- require_relative 'list'
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
@@ -5,9 +5,9 @@
5
5
  # Copyright, 2017, by Kent Gruber.
6
6
  # Copyright, 2022, by Shannon Skipper.
7
7
 
8
- require 'fiber/annotation'
8
+ require "fiber/annotation"
9
9
 
10
- require_relative 'list'
10
+ require_relative "list"
11
11
 
12
12
  module Async
13
13
  # A list of children tasks.
@@ -3,7 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2018-2024, by Samuel Williams.
5
5
 
6
- require_relative 'condition'
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 'notification'
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
@@ -5,7 +5,7 @@
5
5
  # Copyright, 2017, by Kent Gruber.
6
6
  # Copyright, 2018, by Sokolov Yura.
7
7
 
8
- require_relative 'scheduler'
8
+ require_relative "scheduler"
9
9
 
10
10
  module Async
11
11
  # A wrapper around the the scheduler which binds it to the current thread automatically.
@@ -5,13 +5,13 @@
5
5
  # Copyright, 2020, by Jun Jiang.
6
6
  # Copyright, 2021, by Julien Portalier.
7
7
 
8
- require_relative 'clock'
9
- require_relative 'task'
8
+ require_relative "clock"
9
+ require_relative "task"
10
10
 
11
- require 'io/event'
11
+ require "io/event"
12
12
 
13
- require 'console'
14
- require 'resolv'
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
- Kernel.raise(interrupt) if interrupt
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.
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2023, by Samuel Williams.
4
+ # Copyright, 2018-2024, by Samuel Williams.
5
5
 
6
- require_relative 'list'
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 'fiber'
11
- require 'console/event/failure'
10
+ require "fiber"
11
+ require "console"
12
12
 
13
- require_relative 'node'
14
- require_relative 'condition'
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::Event::Failure.for(error).emit(self, "Task may have ended with unhandled exception.", severity: :warn)
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
@@ -3,7 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
- require_relative 'condition'
6
+ require_relative "condition"
7
7
 
8
8
  module Async
9
9
  # A synchronization primitive that allows one task to wait for another task to resolve a value.
data/lib/async/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2017-2024, by Samuel Williams.
5
5
 
6
6
  module Async
7
- VERSION = "2.17.0"
7
+ VERSION = "2.19.0"
8
8
  end
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
- yield task
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.17.0
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-09-05 00:00:00.000000000 Z
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.26'
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.26'
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.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