async 2.42.0 → 2.43.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4b0d66ab9efdfe8910e6eced080524be096c8f6b82b2d2fb5477f00bdb0a6da
4
- data.tar.gz: a35b33bdb575b1c097ccc2fffc3d49eac0ae36054f8bb750d342c21c866961f2
3
+ metadata.gz: 22df54e052923ca32021242839e09cc7150e8d6f63830f697ef43539b68100a0
4
+ data.tar.gz: 3c0c69d9895f2b053550241d7987892b941d0ba2d6c45e98d30b57daf12bbb93
5
5
  SHA512:
6
- metadata.gz: 926c49c93ba5541ee1d3ca5ee3b70024da00f77c71aaf388d604e167f09f664f6e49dc17647ec47ba395f1e9970d36d3e251cc544304caaa2ce37f25617b61f2
7
- data.tar.gz: 2a07815c98380ec7fce0d4a262b5b06756d9379eb72d35edf8a46b06cc7fa34fa01ae81ff2aaba99731d75ba0bbd7deafc41744b27fce4d5e67d4d03e5c90c2e
6
+ metadata.gz: 83b16606c2c1384b38e76dea9ba1b1edbb56009f7088ec35f093df662e3652e7c89eb75a65338216a3ad1d11358fa5f75bb0674fcd5b21339b363beebc86b7c5
7
+ data.tar.gz: 7a68a7833652d477fb940f9fcc98fccc79d2934be1c0351b08e38bc255bf8c627a277d3475aa63df6c1e850938169feae526e9f9c3feae78af3067f7c74ffb73
checksums.yaml.gz.sig CHANGED
Binary file
@@ -3,6 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2017-2025, by Samuel Williams.
5
5
  # Copyright, 2017, by Kent Gruber.
6
+ # Copyright, 2026, by Robert Mosolgo.
6
7
 
7
8
  require "fiber"
8
9
  require_relative "list"
data/lib/async/node.rb CHANGED
@@ -5,6 +5,7 @@
5
5
  # Copyright, 2017, by Kent Gruber.
6
6
  # Copyright, 2022, by Shannon Skipper.
7
7
  # Copyright, 2025-2026, by Shopify Inc.
8
+ # Copyright, 2026, by Kyle Tate.
8
9
 
9
10
  require "fiber/annotation"
10
11
 
@@ -283,9 +284,10 @@ module Async
283
284
  # Attempt to cancel the current node immediately, including all non-transient children. Invokes {#stop_children} to cancel all children.
284
285
  #
285
286
  # @parameter later [Boolean] Whether to defer cancelling until some point in the future.
286
- def cancel(later = false)
287
+ # @parameter cause [Exception | Nil] The cause of the cancel operation.
288
+ def cancel(later = false, cause: $!)
287
289
  # The implementation of this method may defer calling `stop_children`.
288
- stop_children(later)
290
+ stop_children(later, cause: cause)
289
291
  end
290
292
 
291
293
  # Backward compatibility alias for {#cancel}.
@@ -295,9 +297,9 @@ module Async
295
297
  end
296
298
 
297
299
  # Attempt to stop all non-transient children.
298
- private def stop_children(later = false)
300
+ private def stop_children(later = false, cause:)
299
301
  @children&.each do |child|
300
- child.cancel(later) unless child.transient?
302
+ child.cancel(later, cause: cause) unless child.transient?
301
303
  end
302
304
  end
303
305
 
data/lib/async/promise.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2025, by Shopify Inc.
5
5
  # Copyright, 2025-2026, by Samuel Williams.
6
+ # Copyright, 2026, by Kyle Tate.
6
7
 
7
8
  require_relative "error"
8
9
  require_relative "deadline"
@@ -98,7 +99,9 @@ module Async
98
99
  end
99
100
 
100
101
  # Wait with deadline tracking:
101
- until @resolved
102
+ loop do
103
+ break if @resolved
104
+
102
105
  # Get remaining time for this wait iteration:
103
106
  remaining = deadline.remaining
104
107
 
@@ -5,6 +5,7 @@
5
5
  # Copyright, 2020, by Jun Jiang.
6
6
  # Copyright, 2021, by Julien Portalier.
7
7
  # Copyright, 2025-2026, by Shopify Inc.
8
+ # Copyright, 2026, by Kyle Tate.
8
9
 
9
10
  require_relative "clock"
10
11
  require_relative "task"
@@ -514,15 +515,19 @@ module Async
514
515
  # Cancel all children, including transient children.
515
516
  #
516
517
  # @public Since *Async v1*.
517
- def cancel
518
+ def cancel(later = false, cause: $!)
519
+ if @children and !cause
520
+ cause = Cancel::Cause.for("Cancelling task!")
521
+ end
522
+
518
523
  @children&.each do |child|
519
- child.cancel
524
+ child.cancel(later, cause: cause)
520
525
  end
521
526
  end
522
527
 
523
528
  # Backward compatibility alias for cancel.
524
- def stop
525
- cancel
529
+ def stop(...)
530
+ cancel(...)
526
531
  end
527
532
 
528
533
  # Run the event loop, until the scheduler is interrupted or finished.
data/lib/async/task.rb CHANGED
@@ -8,6 +8,7 @@
8
8
  # Copyright, 2023, by Math Ieu.
9
9
  # Copyright, 2025, by Shigeru Nakajima.
10
10
  # Copyright, 2025-2026, by Shopify Inc.
11
+ # Copyright, 2026, by Kyle Tate.
11
12
 
12
13
  require "fiber"
13
14
  require "console"
@@ -333,7 +334,7 @@ module Async
333
334
 
334
335
  if self.cancelled?
335
336
  # If the task is already cancelled, a `cancel` state transition re-enters the same state which is a no-op. However, we will also attempt to cancel any running children too. This can happen if the children did not cancel correctly the first time around. Doing this should probably be considered a bug, but it's better to be safe than sorry.
336
- return cancelled!
337
+ return cancelled!(cause)
337
338
  end
338
339
 
339
340
  # If the fiber is alive, we need to cancel it:
@@ -369,7 +370,7 @@ module Async
369
370
  end
370
371
  else
371
372
  # We are not running, but children might be, so transition directly into cancelled state:
372
- cancel!
373
+ cancel!(cause)
373
374
  end
374
375
  end
375
376
 
@@ -479,7 +480,7 @@ module Async
479
480
  @promise.reject(exception)
480
481
  end
481
482
 
482
- def cancelled!
483
+ def cancelled!(cause = $!)
483
484
  # Console.info(self, status:) {"Task #{self} was cancelled with #{@children&.size.inspect} children!"}
484
485
 
485
486
  # Cancel the promise, specify nil here so that no exception is raised when waiting on the promise:
@@ -489,15 +490,16 @@ module Async
489
490
 
490
491
  begin
491
492
  # We are not running, but children might be so we should stop them:
492
- stop_children(true)
493
- rescue Cancel
493
+ stop_children(true, cause: cause)
494
+ rescue Cancel => exception
494
495
  cancelled = true
496
+ cause ||= exception.cause || exception
495
497
  # If we are cancelling children, and one of them tries to cancel the current task, we should ignore it. We will be cancelled later.
496
498
  retry
497
499
  end
498
500
 
499
501
  if cancelled
500
- raise Cancel, "Cancelling current task!"
502
+ raise Cancel, "Cancelling current task!", cause: cause
501
503
  end
502
504
  end
503
505
 
@@ -505,8 +507,8 @@ module Async
505
507
  cancelled!
506
508
  end
507
509
 
508
- def cancel!
509
- cancelled!
510
+ def cancel!(cause = $!)
511
+ cancelled!(cause)
510
512
 
511
513
  finish!
512
514
  end
@@ -519,8 +521,8 @@ module Async
519
521
  @fiber = Fiber.new(annotation: self.annotation) do
520
522
  begin
521
523
  completed!(yield)
522
- rescue Cancel
523
- cancelled!
524
+ rescue Cancel => exception
525
+ cancelled!(exception.cause || exception)
524
526
  rescue StandardError => error
525
527
  failed!(error)
526
528
  rescue Exception => exception
data/lib/async/version.rb CHANGED
@@ -5,5 +5,5 @@
5
5
 
6
6
  # @namespace
7
7
  module Async
8
- VERSION = "2.42.0"
8
+ VERSION = "2.43.0"
9
9
  end
data/lib/kernel/async.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2019-2024, by Samuel Williams.
5
+ # Copyright, 2026, by Shopify Inc.
5
6
 
6
7
  require_relative "../async/reactor"
7
8
 
data/lib/kernel/sync.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  # Copyright, 2019-2025, by Samuel Williams.
5
5
  # Copyright, 2020, by Brian Morearty.
6
6
  # Copyright, 2024, by Patrik Wenger.
7
- # Copyright, 2025, by Shopify Inc.
7
+ # Copyright, 2025-2026, by Shopify Inc.
8
8
 
9
9
  require_relative "../async/reactor"
10
10
 
data/license.md CHANGED
@@ -36,6 +36,8 @@ Copyright, 2025, by Josh Teeter.
36
36
  Copyright, 2025, by Jatin Goyal.
37
37
  Copyright, 2025, by Yuhi Sato.
38
38
  Copyright, 2026, by Tavian Barnes.
39
+ Copyright, 2026, by Robert Mosolgo.
40
+ Copyright, 2026, by Kyle Tate.
39
41
 
40
42
  Permission is hereby granted, free of charge, to any person obtaining a copy
41
43
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -35,6 +35,10 @@ 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.43.0
39
+
40
+ - Propagate cancellation causes through task trees so child tasks observe the original cancellation cause.
41
+
38
42
  ### v2.42.0
39
43
 
40
44
  - `Sync` and `Async` can now be invoked from a non-blocking fiber that has no scheduler (e.g. inside an `Enumerator` or a bare `Fiber.new`). Previously this raised `RuntimeError: Running scheduler on non-blocking fiber!`. The reactor is now run within `Fiber.blocking`, so the scheduler always runs on a blocking fiber.
@@ -74,11 +78,6 @@ Please see the [project releases](https://socketry.github.io/async/releases/inde
74
78
 
75
79
  - `Async::Clock` now implements `#as_json` and `#to_json` for nicer log formatting.
76
80
 
77
- ### v2.35.2
78
-
79
- - Improved handling of `Process.fork` on Ruby 4+.
80
- - Improve `@promise` state handling in `Task#initialize`, preventing incomplete instances being visible to the scheduler.
81
-
82
81
  ## See Also
83
82
 
84
83
  - [async-http](https://github.com/socketry/async-http) — Asynchronous HTTP client/server.
@@ -97,6 +96,22 @@ We welcome contributions to this project.
97
96
  4. Push to the branch (`git push origin my-new-feature`).
98
97
  5. Create new Pull Request.
99
98
 
99
+ ### Running Tests
100
+
101
+ To run the test suite:
102
+
103
+ ``` shell
104
+ bundle exec sus
105
+ ```
106
+
107
+ ### Making Releases
108
+
109
+ To make a new release:
110
+
111
+ ``` shell
112
+ bundle exec bake gem:release:patch # or minor or major
113
+ ```
114
+
100
115
  ### Developer Certificate of Origin
101
116
 
102
117
  In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
data/releases.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Releases
2
2
 
3
+ ## v2.43.0
4
+
5
+ - Propagate cancellation causes through task trees so child tasks observe the original cancellation cause.
6
+
3
7
  ## v2.42.0
4
8
 
5
9
  - `Sync` and `Async` can now be invoked from a non-blocking fiber that has no scheduler (e.g. inside an `Enumerator` or a bare `Fiber.new`). Previously this raised `RuntimeError: Running scheduler on non-blocking fiber!`. The reactor is now run within `Fiber.blocking`, so the scheduler always runs on a blocking fiber.
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.42.0
4
+ version: 2.43.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -26,11 +26,13 @@ authors:
26
26
  - Julien Portalier
27
27
  - Jun Jiang
28
28
  - Ken Muryoi
29
+ - Kyle Tate
29
30
  - Leon Löchner
30
31
  - Mark Montroy
31
32
  - Masafumi Okura
32
33
  - Masayuki Yamamoto
33
34
  - Math Ieu
35
+ - Robert Mosolgo
34
36
  - Ryan Musgrave
35
37
  - Salim Semaoune
36
38
  - Shannon Skipper
@@ -115,34 +117,6 @@ dependencies:
115
117
  - - "~>"
116
118
  - !ruby/object:Gem::Version
117
119
  version: '1.11'
118
- - !ruby/object:Gem::Dependency
119
- name: metrics
120
- requirement: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '0.12'
125
- type: :runtime
126
- prerelease: false
127
- version_requirements: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '0.12'
132
- - !ruby/object:Gem::Dependency
133
- name: traces
134
- requirement: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '0.18'
139
- type: :runtime
140
- prerelease: false
141
- version_requirements: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '0.18'
146
120
  executables: []
147
121
  extensions: []
148
122
  extra_rdoc_files: []
metadata.gz.sig CHANGED
Binary file