Class: Async::Service::Managed::Service

Inherits:
Generic
  • Object
show all
Includes:
HealthChecker
Defined in:
lib/async/service/managed/service.rb

Overview

A managed service with built-in health checking, restart policies, and process title formatting.

This is the recommended base class for most services that need robust lifecycle management.

Instance Attribute Summary

Attributes inherited from Generic

#The environment which is used to configure the service., #environment

Instance Method Summary collapse

Methods included from HealthChecker

#health_checker

Methods inherited from Generic

#initialize, #name, #stop, #to_h, wrap

Constructor Details

This class inherits a constructor from Async::Service::Generic

Instance Method Details

#emit_prepared(instance, clock) ⇒ Object

Called after the service has been prepared but before it starts running.

Override this method to emit metrics, logs, or perform other actions when the service preparation is complete.



65
66
67
68
# File 'lib/async/service/managed/service.rb', line 65

def emit_prepared(instance, clock)
	# Override in subclasses as needed.
	# Console.info(self, "Prepared...", duration: clock.total)
end

#emit_running(instance, clock) ⇒ Object

Called after the service has started running.

Override this method to emit metrics, logs, or perform other actions when the service begins running.



76
77
78
79
# File 'lib/async/service/managed/service.rb', line 76

def emit_running(instance, clock)
	# Override in subclasses as needed.
	# Console.info(self, "Running...", duration: clock.total)
end

#preload!Object

Preload any resources specified by the environment.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/async/service/managed/service.rb', line 37

def preload!
	if scripts = @evaluator.preload
		root = @evaluator.root
		scripts = Array(scripts)
		
		scripts.each do |path|
			Console.info(self){"Preloading #{path}..."}
			full_path = File.expand_path(path, root)
			require(full_path)
		end
	end
rescue StandardError, LoadError => error
	Console.warn(self, "Service preload failed!", error)
end

#run(instance, evaluator) ⇒ Object

Run the service logic.

Override this method to implement your service. Return an object that represents the running service (e.g., a server, task, or worker pool) for health checking.



30
31
32
33
34
# File 'lib/async/service/managed/service.rb', line 30

def run(instance, evaluator)
	Async do
		sleep
	end
end

#setup(container) ⇒ Object

Set up the container with health checking and process title formatting.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/async/service/managed/service.rb', line 83

def setup(container)
	super
	
	container_options = @evaluator.container_options
	health_check_timeout = container_options[:health_check_timeout]
	
	container.run(**container_options) do |instance|
		clock = Async::Clock.start
		
		Async do
			evaluator = self.environment.evaluator
			server = nil
			
			# If a health check timeout is configured, this block runs periodically to refresh the process title. Without a timeout there is no periodic timer, so the block is never called — the one-shot assignment below handles that case.
			health_checker(instance, health_check_timeout) do
				if server
					instance.name = format_title(evaluator, server)
				end
			end
			
			instance.status!("Preparing...")
			evaluator.prepare!(instance)
			emit_prepared(instance, clock)
			
			instance.status!("Running...")
			server = run(instance, evaluator)
			# Set the process title immediately once the server is available:
			instance.name = format_title(evaluator, server)
			emit_running(instance, clock)
			
			instance.ready!
		end
	end
end

#startObject

Start the service, including preloading resources.



53
54
55
56
57
# File 'lib/async/service/managed/service.rb', line 53

def start
	preload!
	
	super
end