async 2.44.1 → 2.45.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: 0a98ba175586bacb13a3f00ccb770083208e4c8381cbaf17ce4f59fdfc56a85a
4
- data.tar.gz: 6a8614f33cbfa4230e66e12750308a1a339d9a2d6fe8a624b015498c5bc60928
3
+ metadata.gz: 3d9408068579f9a742c20019cf9024bbc4c545c239c4c5178e929c377ac06b6c
4
+ data.tar.gz: 699c17d5dbff6502e1611252982c3595b7b84d57284010222462b838e683d1ac
5
5
  SHA512:
6
- metadata.gz: 0d3c4cd7e58f0eb601e37ffbf8d415c6b66349f268f2b9bec37ed4a945744409ecdb21f13e101cacba2794ea1dd3e6dd3be7a5cf7ca6cc5e67cd557bd65cd11e
7
- data.tar.gz: dc2c1d73dc53df633260e279a20f8cbcb4c40c94b362fc383495e020f750807624c2de5bff446732585b5e2b4121b0ec382de65983db3af23301e937b96b4074
6
+ metadata.gz: a40ca6a441ad341267c5782d089d512b45b36765afbdd1c6382ebb7f931e273cdf29d08ae3a446a0b624618981730c2ee69e15d39adb0956dc44fc1d2ccd2ab9
7
+ data.tar.gz: 325d951d894d7c2fb9cc042534e5e8d76c3edbeb81c061993204ef345af499cfd0fd71ebaae0a6fbbdfd62afdf99a859564554c9cb97dcd730111385948aebf1
checksums.yaml.gz.sig CHANGED
Binary file
@@ -309,10 +309,12 @@ module Async
309
309
  # @parameter timeout [Float | Nil] The maximum time to wait, or if nil, indefinitely.
310
310
  def io_wait(io, events, timeout = nil)
311
311
  fiber = Fiber.current
312
+ expired = false
312
313
 
313
314
  if timeout
314
315
  # If an explicit timeout is specified, we expect that the user will handle it themselves:
315
316
  timer = @timers.after(timeout) do
317
+ expired = true
316
318
  fiber.transfer
317
319
  end
318
320
  elsif timeout = io.timeout
@@ -322,7 +324,13 @@ module Async
322
324
  end
323
325
  end
324
326
 
325
- return @selector.io_wait(fiber, io, events)
327
+ # A selector wait may return a falsy result when the fiber is resumed without the requested IO becoming ready. For example, a deferred unblock from a previous blocking operation may arrive after the fiber has moved on to this wait. Retry these stale or spurious wake-ups without resetting the original timer.
328
+ until result = @selector.io_wait(fiber, io, events)
329
+ # If the original timer resumed the fiber, the falsy result represents the timeout rather than a spurious wake-up:
330
+ return nil if expired
331
+ end
332
+
333
+ return result
326
334
  ensure
327
335
  timer&.cancel!
328
336
  end
@@ -415,7 +423,14 @@ module Async
415
423
  # @returns [Process::Status] A process status instance.
416
424
  # @asynchronous May be non-blocking..
417
425
  def process_wait(pid, flags)
418
- return @selector.process_wait(Fiber.current, pid, flags)
426
+ fiber = Fiber.current
427
+
428
+ # A native process wait may be interrupted before the child exits. io-event reports this as `false` and leaves the retry policy to the scheduler. Retry only `false`, since `nil` is a legitimate result for `Process::WNOHANG`.
429
+ while true
430
+ status = @selector.process_wait(fiber, pid, flags)
431
+
432
+ return status unless status == false
433
+ end
419
434
  end
420
435
 
421
436
  # Wait for the specified IOs to become ready for the specified events.
data/lib/async/version.rb CHANGED
@@ -5,5 +5,5 @@
5
5
 
6
6
  # @namespace
7
7
  module Async
8
- VERSION = "2.44.1"
8
+ VERSION = "2.45.0"
9
9
  end
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.45.0
39
+
40
+ - Fixed scheduler I/O and process waits returning prematurely after stale or interrupted wake-ups. I/O waits now preserve their original timeout, while blocking process waits retry and non-blocking `Process::WNOHANG` waits still return `nil`.
41
+
38
42
  ### v2.44.0
39
43
 
40
44
  - Fixed scheduler cleanup after forking while other fibers are blocked.
@@ -73,11 +77,6 @@ Please see the [project releases](https://socketry.github.io/async/releases/inde
73
77
  - Introduce `Async::Loop` for robust, time-aligned loops.
74
78
  - Add support for `Async::Promise#wait(timeout: N)`.
75
79
 
76
- ### v2.36.0
77
-
78
- - Introduce `Task#wait_all` which recursively waits for all children and self, excepting the current task.
79
- - Introduce `Task#join` as an alias for `Task#wait` for compatibility with `Thread#join` and similar interfaces.
80
-
81
80
  ## See Also
82
81
 
83
82
  - [async-http](https://github.com/socketry/async-http) — Asynchronous HTTP client/server.
data/releases.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Releases
2
2
 
3
+ ## v2.45.0
4
+
5
+ - Fixed scheduler I/O and process waits returning prematurely after stale or interrupted wake-ups. I/O waits now preserve their original timeout, while blocking process waits retry and non-blocking `Process::WNOHANG` waits still return `nil`.
6
+
3
7
  ## v2.44.0
4
8
 
5
9
  - Fixed scheduler cleanup after forking while other fibers are blocked.
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.44.1
4
+ version: 2.45.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -109,14 +109,14 @@ dependencies:
109
109
  requirements:
110
110
  - - "~>"
111
111
  - !ruby/object:Gem::Version
112
- version: '1.11'
112
+ version: '1.21'
113
113
  type: :runtime
114
114
  prerelease: false
115
115
  version_requirements: !ruby/object:Gem::Requirement
116
116
  requirements:
117
117
  - - "~>"
118
118
  - !ruby/object:Gem::Version
119
- version: '1.11'
119
+ version: '1.21'
120
120
  executables: []
121
121
  extensions: []
122
122
  extra_rdoc_files: []
metadata.gz.sig CHANGED
Binary file