Async::ServiceSourceAsyncServiceGeneric

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 environment Environment

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 environment Environment

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 container Async::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 instance Object

The service instance to check.

parameter timeout Numeric

The timeout duration for the health check.

parameter parent Async::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