async-container 0.27.7 → 0.28.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/lib/async/container/controller.rb +2 -2
- data/lib/async/container/forked.rb +4 -4
- data/lib/async/container/generic.rb +31 -7
- data/lib/async/container/notify/console.rb +2 -2
- data/lib/async/container/notify/pipe.rb +2 -2
- data/lib/async/container/threaded.rb +2 -2
- data/lib/async/container/version.rb +1 -1
- data/license.md +1 -1
- data/readme.md +5 -4
- data/releases.md +5 -0
- data.tar.gz.sig +0 -0
- metadata +2 -2
- 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: b600b0cd62cf8c6ba832a6022ba2e2aeca1709264b696277fe11055074d36ea3
|
|
4
|
+
data.tar.gz: 456e1cfb343619036dfb70ac693f302b3a0dc61c0a1e3d698544c5632fabb7f8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e72593aa02a1ad84c7223d178cf6f89bd9dbd8387539a0c77c50bcec9ac03a118a978cc3e87544b850cdeebb6a1d3925ddcee01e3866129cd8a395aae586f056
|
|
7
|
+
data.tar.gz: 24e370fbd183a791179cb7fbd6089e513bbdf1767af8fc955cf3e6690c937f075a2cb255915172bb46d1dc08d6995595deaf3e6d3fc39cf643a558d21e14bd7d
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2018-
|
|
4
|
+
# Copyright, 2018-2026, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
require_relative "error"
|
|
7
7
|
require_relative "best"
|
|
@@ -160,7 +160,7 @@ module Async
|
|
|
160
160
|
def reload
|
|
161
161
|
@notify&.reloading!
|
|
162
162
|
|
|
163
|
-
Console.info(self)
|
|
163
|
+
Console.info(self){"Reloading container: #{@container}..."}
|
|
164
164
|
|
|
165
165
|
begin
|
|
166
166
|
self.setup(@container)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2017-
|
|
4
|
+
# Copyright, 2017-2026, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
require_relative "error"
|
|
7
7
|
|
|
@@ -101,9 +101,9 @@ module Async
|
|
|
101
101
|
self.new(**options) do |process|
|
|
102
102
|
::Process.fork do
|
|
103
103
|
# We use `Thread.current.raise(...)` so that exceptions are filtered through `Thread.handle_interrupt` correctly.
|
|
104
|
-
Signal.trap(:INT)
|
|
105
|
-
Signal.trap(:TERM)
|
|
106
|
-
Signal.trap(:HUP)
|
|
104
|
+
Signal.trap(:INT){::Thread.current.raise(Interrupt)}
|
|
105
|
+
Signal.trap(:TERM){::Thread.current.raise(Terminate)}
|
|
106
|
+
Signal.trap(:HUP){::Thread.current.raise(Restart)}
|
|
107
107
|
|
|
108
108
|
# This could be a configuration option:
|
|
109
109
|
::Thread.handle_interrupt(SignalException => :immediate) do
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2019-
|
|
4
|
+
# Copyright, 2019-2026, by Samuel Williams.
|
|
5
5
|
# Copyright, 2025, by Marc-André Cournoyer.
|
|
6
6
|
|
|
7
7
|
require "etc"
|
|
@@ -163,12 +163,20 @@ module Async
|
|
|
163
163
|
child.kill!
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
+
protected def startup_failed!(child, age_clock, startup_timeout)
|
|
167
|
+
Console.warn(self, "Child failed startup!", child: child, age: age_clock.total, startup_timeout: startup_timeout)
|
|
168
|
+
|
|
169
|
+
# If the child has failed the startup, we assume the worst and kill it immediately:
|
|
170
|
+
child.kill!
|
|
171
|
+
end
|
|
172
|
+
|
|
166
173
|
# Spawn a child instance into the container.
|
|
167
174
|
# @parameter name [String] The name of the child instance.
|
|
168
175
|
# @parameter restart [Boolean] Whether to restart the child instance if it fails.
|
|
169
176
|
# @parameter key [Symbol] A key used for reloading child instances.
|
|
170
177
|
# @parameter health_check_timeout [Numeric | Nil] The maximum time a child instance can run without updating its state, before it is terminated as unhealthy.
|
|
171
|
-
|
|
178
|
+
# @parameter startup_timeout [Numeric | Nil] The maximum time a child instance can run without becoming ready, before it is terminated as unhealthy.
|
|
179
|
+
def spawn(name: nil, restart: false, key: nil, health_check_timeout: nil, startup_timeout: nil, &block)
|
|
172
180
|
name ||= UNNAMED
|
|
173
181
|
|
|
174
182
|
if mark?(key)
|
|
@@ -187,8 +195,8 @@ module Async
|
|
|
187
195
|
|
|
188
196
|
Console.debug(self, "Started child.", child: child, spawn: {key: key, restart: restart, health_check_timeout: health_check_timeout}, statistics: @statistics)
|
|
189
197
|
|
|
190
|
-
# If a health check is specified, we will monitor the child process and terminate it if it does not update its state within the specified time.
|
|
191
|
-
if health_check_timeout
|
|
198
|
+
# If a health check or startup timeout is specified, we will monitor the child process and terminate it if it does not update its state within the specified time.
|
|
199
|
+
if health_check_timeout || startup_timeout
|
|
192
200
|
age_clock = state[:age] = Clock.start
|
|
193
201
|
end
|
|
194
202
|
|
|
@@ -198,12 +206,28 @@ module Async
|
|
|
198
206
|
status = @group.wait_for(child) do |message|
|
|
199
207
|
case message
|
|
200
208
|
when :health_check!
|
|
201
|
-
if
|
|
202
|
-
|
|
209
|
+
if state[:ready]
|
|
210
|
+
# If a health check timeout is specified, we will monitor the child process and terminate it if it does not update its state within the specified time.
|
|
211
|
+
if health_check_timeout
|
|
212
|
+
if health_check_timeout < age_clock.total
|
|
213
|
+
health_check_failed!(child, age_clock, health_check_timeout)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
else
|
|
217
|
+
# If a startup timeout is specified, we will monitor the child process and terminate it if it does not become ready within the specified time.
|
|
218
|
+
if startup_timeout
|
|
219
|
+
if startup_timeout < age_clock.total
|
|
220
|
+
startup_failed!(child, age_clock, startup_timeout)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
203
223
|
end
|
|
204
224
|
else
|
|
205
225
|
state.update(message)
|
|
206
|
-
|
|
226
|
+
|
|
227
|
+
# Reset the age clock if the child has become ready:
|
|
228
|
+
if state[:ready]
|
|
229
|
+
age_clock&.reset!
|
|
230
|
+
end
|
|
207
231
|
end
|
|
208
232
|
end
|
|
209
233
|
rescue => error
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2020-
|
|
4
|
+
# Copyright, 2020-2026, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
require_relative "client"
|
|
7
7
|
|
|
@@ -25,7 +25,7 @@ module Async
|
|
|
25
25
|
|
|
26
26
|
# Send a message to the console.
|
|
27
27
|
def send(level: :info, **message)
|
|
28
|
-
@logger.public_send(level, self)
|
|
28
|
+
@logger.public_send(level, self){message}
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Send an error message to the console.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2020-
|
|
4
|
+
# Copyright, 2020-2026, by Samuel Williams.
|
|
5
5
|
# Copyright, 2020, by Juan Antonio Martín Lucas.
|
|
6
6
|
|
|
7
7
|
require_relative "client"
|
|
@@ -22,7 +22,7 @@ module Async
|
|
|
22
22
|
self.new(::IO.for_fd(descriptor.to_i))
|
|
23
23
|
end
|
|
24
24
|
rescue Errno::EBADF => error
|
|
25
|
-
Console.error(self)
|
|
25
|
+
Console.error(self){error}
|
|
26
26
|
|
|
27
27
|
return nil
|
|
28
28
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2017-
|
|
4
|
+
# Copyright, 2017-2026, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
require_relative "generic"
|
|
7
7
|
require_relative "channel"
|
|
@@ -274,7 +274,7 @@ module Async
|
|
|
274
274
|
# Invoked by the @waiter thread to indicate the outcome of the child thread.
|
|
275
275
|
def finished(error = nil)
|
|
276
276
|
if error
|
|
277
|
-
Console.error(self)
|
|
277
|
+
Console.error(self){error}
|
|
278
278
|
end
|
|
279
279
|
|
|
280
280
|
@status ||= Status.new(error)
|
data/license.md
CHANGED
data/readme.md
CHANGED
|
@@ -26,6 +26,11 @@ Please see the [project documentation](https://socketry.github.io/async-containe
|
|
|
26
26
|
|
|
27
27
|
Please see the [project releases](https://socketry.github.io/async-container/releases/index) for all releases.
|
|
28
28
|
|
|
29
|
+
### v0.28.0
|
|
30
|
+
|
|
31
|
+
- Add `startup_timeout` parameter to `spawn` and `run` methods for detecting processes that hang during startup and never become ready.
|
|
32
|
+
- Health check timeout now only applies after a process becomes ready, preventing premature timeouts for slow-starting applications.
|
|
33
|
+
|
|
29
34
|
### v0.27.5
|
|
30
35
|
|
|
31
36
|
- Make the child handling more robust in the face of exceptions.
|
|
@@ -64,10 +69,6 @@ Please see the [project releases](https://socketry.github.io/async-container/rel
|
|
|
64
69
|
|
|
65
70
|
- Add support for health check failure metrics.
|
|
66
71
|
|
|
67
|
-
### v0.23.0
|
|
68
|
-
|
|
69
|
-
- [Add support for `NOTIFY_LOG` for Kubernetes readiness probes.](https://socketry.github.io/async-container/releases/index#add-support-for-notify_log-for-kubernetes-readiness-probes.)
|
|
70
|
-
|
|
71
72
|
## Contributing
|
|
72
73
|
|
|
73
74
|
We welcome contributions to this project.
|
data/releases.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.28.0
|
|
4
|
+
|
|
5
|
+
- Add `startup_timeout` parameter to `spawn` and `run` methods for detecting processes that hang during startup and never become ready.
|
|
6
|
+
- Health check timeout now only applies after a process becomes ready, preventing premature timeouts for slow-starting applications.
|
|
7
|
+
|
|
3
8
|
## v0.27.5
|
|
4
9
|
|
|
5
10
|
- Make the child handling more robust in the face of exceptions.
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: async-container
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.28.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
107
|
version: '0'
|
|
108
108
|
requirements: []
|
|
109
|
-
rubygems_version:
|
|
109
|
+
rubygems_version: 4.0.3
|
|
110
110
|
specification_version: 4
|
|
111
111
|
summary: Abstract container-based parallelism using threads and processes where appropriate.
|
|
112
112
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|