Skip to content

Commit 3ae6b62

Browse files
Run container tests in async context
1 parent 2769476 commit 3ae6b62

3 files changed

Lines changed: 46 additions & 14 deletions

File tree

fixtures/container_context.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
require "async"
4+
require "async/container/group"
5+
6+
module ContainerContext
7+
def container_context(&block)
8+
# Newer async-container supervises containers using Async tasks, while
9+
# released versions can fail when forking under a scheduler on Ruby 3.x.
10+
if Async::Container::Group.method_defined?(:supervise)
11+
Sync(&block)
12+
else
13+
block.call
14+
end
15+
end
16+
end

test/async/service/managed/service.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010
require "async"
1111

1212
require "sus/fixtures/async/scheduler_context"
13+
require "container_context"
1314

1415
describe Async::Service::Managed::Service do
16+
include ContainerContext
17+
1518
let(:configuration) do
1619
Async::Service::Configuration.build do
1720
service "test-container" do
@@ -365,15 +368,15 @@ def name = @name
365368
let(:controller) {Async::Service::Controller.for(test_service)}
366369

367370
it "runs service with health checking and no restarts when async context is present" do
368-
container = Async::Container.new
369-
370-
begin
371+
container_context do
372+
container = Async::Container.new
373+
371374
controller.setup(container)
372375
controller.start
373376
sleep(0.03)
374377
ensure
375378
controller.stop
376-
container.stop
379+
container&.stop
377380
end
378381
end
379382
end

test/async/service/policy.rb

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
require "async/container/best"
77
require "async/service/policy"
88
require "async/container/statistics"
9+
require "container_context"
910

1011
describe Async::Service::Policy do
12+
include ContainerContext
13+
1114
let(:policy) {subject.new(maximum_failures: 5, window: 10)}
1215

1316
with "::DEFAULT" do
@@ -161,18 +164,28 @@ def success_status.success?; true; end
161164

162165
with "concurrent failures" do
163166
it "only stops container once when multiple children fail simultaneously" do
164-
container = Async::Container.best_container_class.new(policy: policy)
165-
expect(container).to receive(:stop)
166-
167-
# Spawn 10 children that all fail immediately:
168-
10.times do |i|
169-
container.spawn(name: "worker-#{i}") do |instance|
170-
instance.ready!
171-
exit(1)
167+
container_context do
168+
container = Async::Container.best_container_class.new(policy: policy)
169+
stop_count = 0
170+
original_stop = container.method(:stop)
171+
172+
container.define_singleton_method(:stop) do |*arguments|
173+
stop_count += 1
174+
original_stop.call(*arguments)
175+
end
176+
177+
# Spawn 10 children that all fail immediately:
178+
10.times do |i|
179+
container.spawn(name: "worker-#{i}") do |instance|
180+
instance.ready!
181+
exit(1)
182+
end
172183
end
184+
185+
container.wait
186+
187+
expect(stop_count).to be == 1
173188
end
174-
175-
container.wait
176189
end
177190
end
178191
end

0 commit comments

Comments
 (0)