Skip to content

Commit 96588ed

Browse files
Fix usage of Async in Managed::Service.
1 parent 51513c7 commit 96588ed

File tree

3 files changed

+109
-9
lines changed

3 files changed

+109
-9
lines changed

lib/async/service/managed/service.rb

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def preload!
4949
rescue StandardError, LoadError => error
5050
Console.warn(self, "Service preload failed!", error)
5151
end
52-
52+
5353
# Start the service, including preloading resources.
5454
def start
5555
preload!
@@ -66,17 +66,18 @@ def setup(container)
6666
health_check_timeout = container_options[:health_check_timeout]
6767

6868
container.run(**container_options) do |instance|
69-
evaluator = self.environment.evaluator
70-
71-
server = run(instance, evaluator)
72-
73-
health_checker(instance) do
74-
instance.name = format_title(evaluator, server)
69+
Async do
70+
evaluator = self.environment.evaluator
71+
72+
server = run(instance, evaluator)
73+
74+
health_checker(instance) do
75+
instance.name = format_title(evaluator, server)
76+
end
7577
end
7678
end
77-
end
79+
end
7880
end
7981
end
8082
end
8183
end
82-

releases.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Releases
22

3+
## Unreleased
4+
5+
- `Managed::Service` should run within `Async do ... end`.
6+
37
## v0.15.0
48

59
- Rename `ContainerEnvironment` and `ContainerService` to `Managed::Environment` and `Managed::Service` respectively.

test/async/service/managed/service.rb

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,73 @@
6262
expect(options_captured[:restart]).to be == true
6363
end
6464

65+
with "integration test" do
66+
include Sus::Fixtures::Async::SchedulerContext
67+
68+
it "executes the container block with async context and health checking" do
69+
container = Async::Container.new
70+
block_executed = false
71+
health_checker_called = false
72+
instance_ready_called = false
73+
74+
# Create a mock instance that tracks ready! calls
75+
mock_instance = Object.new
76+
def mock_instance.ready!
77+
@ready_called = true
78+
end
79+
80+
def mock_instance.ready_called?
81+
@ready_called || false
82+
end
83+
84+
def mock_instance.name=(value)
85+
@name = value
86+
end
87+
88+
def mock_instance.name
89+
@name
90+
end
91+
92+
# Mock container.run to actually execute the block
93+
mock(container) do |mock|
94+
mock.replace(:run) do |**options, &block|
95+
# Execute the block in an async context (simulating what container does)
96+
Async do
97+
block.call(mock_instance)
98+
end
99+
end
100+
end
101+
102+
# Override run to track execution
103+
service_class = Class.new(Async::Service::Managed::Service) do
104+
def run(instance, evaluator)
105+
@run_called = true
106+
super
107+
end
108+
109+
def run_called?
110+
@run_called || false
111+
end
112+
end
113+
114+
test_service = service_class.new(service.environment)
115+
116+
# Setup should execute without errors
117+
expect{test_service.setup(container)
118+
}.not.to raise_exception
119+
120+
# Give async tasks time to execute
121+
sleep(0.1)
122+
123+
# Verify run was called
124+
expect(test_service.run_called?).to be == true
125+
126+
# Verify health checker would have been called (it creates async tasks)
127+
# The instance should have been marked ready by the health checker
128+
expect(mock_instance.ready_called?).to be == true
129+
end
130+
end
131+
65132
with "custom managed service options" do
66133
let(:configuration) do
67134
Async::Service::Configuration.build do
@@ -207,4 +274,32 @@
207274
task.stop
208275
end
209276
end
277+
278+
with "integration test with controller" do
279+
let(:configuration) do
280+
Async::Service::Configuration.build do
281+
service "test-managed" do
282+
service_class Async::Service::Managed::Service
283+
include Async::Service::Managed::Environment
284+
285+
count 1
286+
287+
# Very short timeout to detect failures quickly:
288+
health_check_timeout 0.01
289+
end
290+
end
291+
end
292+
293+
let(:test_service) {configuration.services.first}
294+
let(:controller) {Async::Service::Controller.for(test_service)}
295+
296+
it "runs service with health checking and no restarts when async context is present" do
297+
container = Async::Container.new
298+
299+
controller.setup(container)
300+
controller.start
301+
sleep(0.03)
302+
controller.stop
303+
end
304+
end
210305
end

0 commit comments

Comments
 (0)