Skip to content

Commit db97f98

Browse files
authored
Ensure the container is stopped if it's not correctly started. (#32)
1 parent 9fb616f commit db97f98

File tree

3 files changed

+68
-6
lines changed

3 files changed

+68
-6
lines changed

lib/async/container/controller.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,20 @@ def restart
135135
raise SetupError, container
136136
end
137137

138-
# Make this swap as atomic as possible:
138+
# The following swap should be atomic:
139139
old_container = @container
140140
@container = container
141+
container = nil
142+
143+
if old_container
144+
Console.logger.debug(self, "Stopping old container...")
145+
old_container&.stop
146+
end
141147

142-
Console.logger.debug(self, "Stopping old container...")
143-
old_container&.stop
144148
@notify&.ready!
145-
rescue
149+
ensure
146150
# If we are leaving this function with an exception, try to kill the container:
147151
container&.stop(false)
148-
149-
raise
150152
end
151153

152154
# Reload the existing container. Children instances will be reloaded using `SIGHUP`.

test/async/container/.bad.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
# Released under the MIT License.
5+
# Copyright, 2020-2022, by Samuel Williams.
6+
7+
require_relative '../../../lib/async/container/controller'
8+
9+
class Bad < Async::Container::Controller
10+
def setup(container)
11+
container.run(name: "bad", count: 1, restart: true) do |instance|
12+
# Deliberately missing call to `instance.ready!`:
13+
# instance.ready!
14+
15+
$stdout.puts "Ready..."
16+
$stdout.flush
17+
18+
sleep
19+
ensure
20+
$stdout.puts "Exiting..."
21+
$stdout.flush
22+
end
23+
end
24+
end
25+
26+
controller = Bad.new
27+
28+
controller.run

test/async/container/controller.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,38 @@ def controller.setup(container)
8888
end
8989
end
9090

91+
with 'bad controller' do
92+
let(:controller_path) {File.expand_path(".bad.rb", __dir__)}
93+
94+
let(:pipe) {IO.pipe}
95+
let(:input) {pipe.first}
96+
let(:output) {pipe.last}
97+
98+
let(:pid) {@pid}
99+
100+
def before
101+
@pid = Process.spawn("bundle", "exec", controller_path, out: output)
102+
output.close
103+
104+
super
105+
end
106+
107+
def after
108+
Process.kill(:TERM, @pid)
109+
Process.wait(@pid)
110+
111+
super
112+
end
113+
114+
it "fails to start" do
115+
expect(input.gets).to be == "Ready...\n"
116+
117+
Process.kill(:INT, @pid)
118+
119+
expect(input.gets).to be == "Exiting...\n"
120+
end
121+
end
122+
91123
with 'signals' do
92124
let(:controller_path) {File.expand_path(".dots.rb", __dir__)}
93125

0 commit comments

Comments
 (0)