async-signals 0.1.0 → 0.2.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 +0 -0
- data/context/getting-started.md +21 -0
- data/guides/getting-started/readme.md +21 -0
- data/lib/async/signals/ignore.rb +31 -0
- data/lib/async/signals/version.rb +1 -1
- data/lib/async/signals.rb +11 -0
- data/readme.md +5 -0
- data/releases.md +4 -0
- data.tar.gz.sig +0 -0
- metadata +2 -1
- 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: d11c9736e5b39139e1875619f776b0ffa1153c6782e3aaed48b0703ec50865ad
|
|
4
|
+
data.tar.gz: c5eca9092f34e538c9b76bc3feebdc005ca9a7fe8ac1283f77aac16602b245e3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 832500ae1ef771269fa4d05eb6322332ab70e1d9003594001d2ef18831bcd8c4430c65005ca087b167efde19ba765ef5f273f7add5ec639f9b840769dcbf1488
|
|
7
|
+
data.tar.gz: 937153c1ddf69d8211150f428d5f674f6992cd88526b4b82e1a4a0e26395d238e427a96e378cc69b46b3415a323d087354df9a8c932f881378f22a0fa260389f
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/context/getting-started.md
CHANGED
|
@@ -25,6 +25,7 @@ Ruby signal handlers are process-wide. Calling `Signal.trap` for the same signal
|
|
|
25
25
|
- {ruby Async::Signals::Handlers} represents a configurable set of signal handlers for one consumer.
|
|
26
26
|
- {ruby Async::Signals::Controller} owns the process-wide `Signal.trap` entries while handler sets are installed.
|
|
27
27
|
- {ruby Async::Signals.install} installs a handler set using the default process-wide controller.
|
|
28
|
+
- {ruby Async::Signals::Ignore} provides a no-op signal backend for code that should not install process signal traps.
|
|
28
29
|
- {ruby Async::Signals.reset!} removes all active handlers and restores the previous signal traps.
|
|
29
30
|
|
|
30
31
|
Each handler set can trap or ignore signals independently. When multiple handler sets trap the same signal, `async-signals` installs one Ruby signal trap and dispatches the signal to each active handler.
|
|
@@ -128,6 +129,26 @@ end
|
|
|
128
129
|
|
|
129
130
|
The installed handlers are snapshotted when they are installed. Later changes to the handler set do not affect an existing registration.
|
|
130
131
|
|
|
132
|
+
### Choosing a Signal Backend
|
|
133
|
+
|
|
134
|
+
Use {ruby Async::Signals.default} when a component should install process signal handlers only while running on the main thread. It returns {ruby Async::Signals} on the main thread and {ruby Async::Signals::Ignore} on other threads.
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
require "async/signals"
|
|
138
|
+
|
|
139
|
+
handlers = Async::Signals::Handlers.new
|
|
140
|
+
handlers.trap(:TERM) do
|
|
141
|
+
puts "Stopping..."
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
Async::Signals.default.install(handlers) do
|
|
145
|
+
# Process signal handlers are active only on the main thread.
|
|
146
|
+
sleep
|
|
147
|
+
end
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Use {ruby Async::Signals::Ignore} directly when a component is controlled by its parent and should not subscribe to process-wide signals.
|
|
151
|
+
|
|
131
152
|
## Forking
|
|
132
153
|
|
|
133
154
|
Signal traps are inherited across `fork`. On Ruby implementations that support `Process._fork`, `async-signals` automatically resets inherited signal state in the forked child so the child does not keep handler registrations from the parent process.
|
|
@@ -25,6 +25,7 @@ Ruby signal handlers are process-wide. Calling `Signal.trap` for the same signal
|
|
|
25
25
|
- {ruby Async::Signals::Handlers} represents a configurable set of signal handlers for one consumer.
|
|
26
26
|
- {ruby Async::Signals::Controller} owns the process-wide `Signal.trap` entries while handler sets are installed.
|
|
27
27
|
- {ruby Async::Signals.install} installs a handler set using the default process-wide controller.
|
|
28
|
+
- {ruby Async::Signals::Ignore} provides a no-op signal backend for code that should not install process signal traps.
|
|
28
29
|
- {ruby Async::Signals.reset!} removes all active handlers and restores the previous signal traps.
|
|
29
30
|
|
|
30
31
|
Each handler set can trap or ignore signals independently. When multiple handler sets trap the same signal, `async-signals` installs one Ruby signal trap and dispatches the signal to each active handler.
|
|
@@ -128,6 +129,26 @@ end
|
|
|
128
129
|
|
|
129
130
|
The installed handlers are snapshotted when they are installed. Later changes to the handler set do not affect an existing registration.
|
|
130
131
|
|
|
132
|
+
### Choosing a Signal Backend
|
|
133
|
+
|
|
134
|
+
Use {ruby Async::Signals.default} when a component should install process signal handlers only while running on the main thread. It returns {ruby Async::Signals} on the main thread and {ruby Async::Signals::Ignore} on other threads.
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
require "async/signals"
|
|
138
|
+
|
|
139
|
+
handlers = Async::Signals::Handlers.new
|
|
140
|
+
handlers.trap(:TERM) do
|
|
141
|
+
puts "Stopping..."
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
Async::Signals.default.install(handlers) do
|
|
145
|
+
# Process signal handlers are active only on the main thread.
|
|
146
|
+
sleep
|
|
147
|
+
end
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Use {ruby Async::Signals::Ignore} directly when a component is controlled by its parent and should not subscribe to process-wide signals.
|
|
151
|
+
|
|
131
152
|
## Forking
|
|
132
153
|
|
|
133
154
|
Signal traps are inherited across `fork`. On Ruby implementations that support `Process._fork`, `async-signals` automatically resets inherited signal state in the forked child so the child does not keep handler registrations from the parent process.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2026, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
module Async
|
|
7
|
+
module Signals
|
|
8
|
+
# Provides a no-op signal backend.
|
|
9
|
+
module Ignore
|
|
10
|
+
# Represents a no-op signal registration.
|
|
11
|
+
class Registration
|
|
12
|
+
# Close the registration.
|
|
13
|
+
def close
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
REGISTRATION = Registration.new.freeze
|
|
18
|
+
|
|
19
|
+
# Ignore signal handlers.
|
|
20
|
+
# @parameter handlers [Handlers] The handlers to ignore.
|
|
21
|
+
# @returns [Registration] The no-op registration.
|
|
22
|
+
def self.install(handlers)
|
|
23
|
+
if block_given?
|
|
24
|
+
yield handlers
|
|
25
|
+
else
|
|
26
|
+
REGISTRATION
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/async/signals.rb
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
require_relative "signals/version"
|
|
7
7
|
require_relative "signals/handlers"
|
|
8
8
|
require_relative "signals/controller"
|
|
9
|
+
require_relative "signals/ignore"
|
|
9
10
|
|
|
10
11
|
module Async
|
|
11
12
|
# Provides composable process signal handling.
|
|
@@ -18,6 +19,16 @@ module Async
|
|
|
18
19
|
CONTROLLER
|
|
19
20
|
end
|
|
20
21
|
|
|
22
|
+
# The default signal backend for the current thread.
|
|
23
|
+
# @returns [Async::Signals | Async::Signals::Ignore] The default signal backend.
|
|
24
|
+
def self.default
|
|
25
|
+
if ::Thread.current == ::Thread.main
|
|
26
|
+
self
|
|
27
|
+
else
|
|
28
|
+
Ignore
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
21
32
|
# Install signal handlers using the process-wide signal controller.
|
|
22
33
|
# @parameter handlers [Handlers] The handlers to install.
|
|
23
34
|
# @returns [Controller::Registration] The active registration.
|
data/readme.md
CHANGED
|
@@ -9,6 +9,7 @@ Composable process signal handling for Ruby.
|
|
|
9
9
|
- Coordinates process-wide signal traps across multiple consumers.
|
|
10
10
|
- Supports overlapping signal handlers without replacing each other.
|
|
11
11
|
- Supports scoped ignore handlers for specific signals.
|
|
12
|
+
- Provides a no-op signal backend for components that should not install process signal traps.
|
|
12
13
|
- Restores previous signal traps when handlers are removed.
|
|
13
14
|
- Resets inherited signal state in forked children on Ruby implementations with `Process._fork`.
|
|
14
15
|
- Documents thread-safe signal handler design for portable signal delivery.
|
|
@@ -23,6 +24,10 @@ Please see the [project documentation](https://socketry.github.io/async-signals/
|
|
|
23
24
|
|
|
24
25
|
Please see the [project releases](https://socketry.github.io/async-signals/releases/index) for all releases.
|
|
25
26
|
|
|
27
|
+
### v0.2.0
|
|
28
|
+
|
|
29
|
+
- Add `Async::Signals.default` and `Async::Signals::Ignore` for selecting process signal handling based on the current thread.
|
|
30
|
+
|
|
26
31
|
### v0.1.0
|
|
27
32
|
|
|
28
33
|
- Initial release.
|
data/releases.md
CHANGED
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: async-signals
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -49,6 +49,7 @@ files:
|
|
|
49
49
|
- lib/async/signals.rb
|
|
50
50
|
- lib/async/signals/controller.rb
|
|
51
51
|
- lib/async/signals/handlers.rb
|
|
52
|
+
- lib/async/signals/ignore.rb
|
|
52
53
|
- lib/async/signals/version.rb
|
|
53
54
|
- license.md
|
|
54
55
|
- readme.md
|
metadata.gz.sig
CHANGED
|
Binary file
|