class Generic
	
	
	Captures the stateful behaviour of a specific service. Specifies the interfaces required by derived classes.
Designed to be invoked within an Async::Controller::Container.
Definitions
def self.wrap(environment)
Convert the given environment into a service if possible.
Signature
	- 
					parameter 
environmentEnvironment The environment to use to construct the service.
- 
					returns 
Generic | Nil The constructed service if the environment specifies a service class.
Implementation
						def self.wrap(environment)
	evaluator = environment.evaluator
	
	if evaluator.key?(:service_class)
		if service_class = evaluator.service_class
			return service_class.new(environment, evaluator)
		end
	end
end
					def initialize(environment, evaluator = environment.evaluator)
Initialize the service from the given environment.
Signature
	- 
					parameter 
environmentEnvironment 
Implementation
						def initialize(environment, evaluator = environment.evaluator)
	@environment = environment
	@evaluator = evaluator
end
					attr :environment
Signature
	- 
					attribute 
Environment The environment which is used to configure the service.
def to_h
Convert the service evaluator to a hash.
Signature
	- 
					returns 
Hash A hash representation of the evaluator.
Implementation
						def to_h
	@evaluator.to_h
end
					def name
The name of the service - used for informational purposes like logging.
e.g. myapp.com.
Implementation
						def name
	@evaluator.name
end
					def start
Start the service. Called before the container setup.
Implementation
						def start
	Console.debug(self) {"Starting service #{self.name}..."}
end
					def setup(container)
Setup the service into the specified container.
Signature
	- 
					parameter 
containerAsync::Container::Generic 
Implementation
						def setup(container)
	Console.debug(self) {"Setting up service #{self.name}..."}
end
					def stop(graceful = true)
Stop the service. Called after the container is stopped.
Implementation
						def stop(graceful = true)
	Console.debug(self) {"Stopping service #{self.name}..."}
end
					def health_checker(instance, timeout = @evaluator.health_check_timeout, parent: Async::Task.current, &block)
Start the health checker.
If a timeout is specified, a transient child task will be scheduled, which will yield the instance if a block is given, then mark the instance as ready, and finally sleep for half the health check duration (so that we guarantee that the health check runs in time).
If a timeout is not specified, the health checker will yield the instance immediately and then mark the instance as ready.
Signature
	- 
					parameter 
instanceObject The service instance to check.
- 
					parameter 
timeoutNumeric The timeout duration for the health check.
- 
					parameter 
parentAsync::Task The parent task to run the health checker in.
- 
					yields 
{|instance| ...} If a block is given, it will be called with the service instance at least once.
Implementation
						def health_checker(instance, timeout = @evaluator.health_check_timeout, parent: Async::Task.current, &block)
	if timeout
		parent.async(transient: true) do
			while true
				if block_given?
					yield(instance)
				end
				
				instance.ready!
				
				sleep(timeout / 2)
			end
		end
	else
		if block_given?
			yield(instance)
		end
		
		instance.ready!
	end
end