diff --git a/lib/async/service/supervisor/supervised.rb b/lib/async/service/supervisor/supervised.rb index 3789760..62b2847 100644 --- a/lib/async/service/supervisor/supervised.rb +++ b/lib/async/service/supervisor/supervised.rb @@ -56,12 +56,15 @@ def utilization_registry end # The supervised worker for the current process. + # @parameter state [Hash | Nil] Additional state to register with the supervisor. # @returns [Worker] The worker client. - def supervisor_worker + def supervisor_worker(state: nil) + state = self.supervisor_worker_state.merge(state || {}) + Worker.new( process_id: Process.pid, endpoint: supervisor_endpoint, - state: self.supervisor_worker_state, + state: state, utilization_schema: self.utilization_schema, utilization_registry: self.utilization_registry, ) @@ -70,11 +73,12 @@ def supervisor_worker # Create a supervised worker for the given instance. # # @parameter instance [Async::Container::Instance] The container instance. + # @parameter state [Hash | Nil] Additional state to register with the supervisor. # @returns [Worker] The worker client. - def prepare!(instance) + def prepare!(instance, state: nil) super(instance) - supervisor_worker.run + supervisor_worker(state: state).run end end end diff --git a/releases.md b/releases.md index b37fe7e..7209132 100644 --- a/releases.md +++ b/releases.md @@ -1,5 +1,9 @@ # Releases +## Unreleased + + - Allow supervised services to merge additional worker state during preparation and worker construction. + ## v0.17.0 - Add opt-in `metrics` and `traces` providers for supervisor process metrics, utilization metrics, and worker lifecycle tracing. diff --git a/test/async/service/supervised.rb b/test/async/service/supervised.rb index 502283c..15636b6 100644 --- a/test/async/service/supervised.rb +++ b/test/async/service/supervised.rb @@ -56,5 +56,28 @@ def setup(container) ensure worker_task&.stop end + + it "can register explicit worker state" do + environment = Async::Service::Environment.build(root: @root) do + name "simple-service" + + service_class {SimpleService} + + include Async::Service::Supervisor::Supervised + end + + additional_state = { + endpoint: {name: "http", addresses: [{address: "127.0.0.1", port: 9292}]}, + } + worker = environment.evaluator.supervisor_worker(state: additional_state) + worker_task = worker.run + + event = registration_monitor.pop + expect(event.supervisor_controller.state).to be == { + name: "simple-service", + endpoint: additional_state[:endpoint], + } + ensure + worker_task&.stop + end end -