Async::Service::ChaosKittySourceAsyncServiceChaosKittyServer

class Server

The server represents the main chaos process which is responsible for unleashing chaos on connected victims.

Various chaos operations can be executed by the server, such as causing delays, raising errors, and consuming resources. The server is also responsible for managing the lifecycle of the chaos operations, which can be used to wreak havoc on the connected workers.

Definitions

def initialize(chaos_operations: [], endpoint: ChaosKitty.endpoint, **options)

Initialize a new chaos server.

Signature

parameter chaos_operations Array

The chaos operations to run.

parameter endpoint IO::Endpoint

The endpoint to listen on.

Implementation

def initialize(chaos_operations: [], endpoint: ChaosKitty.endpoint, **options)
	super(endpoint, **options)
	
	@chaos_operations = chaos_operations
	@controllers = {}
	@next_id = 0
end

def next_id

Allocate the next unique sequential ID.

Signature

returns Integer

A unique sequential ID.

Implementation

def next_id
	@next_id += 1
end

def add(controller)

Add a controller to the server.

Validates that the controller has been properly registered with an ID and checks for ID collisions before adding it to tracking.

Signature

parameter controller ChaosController

The controller to add.

raises RuntimeError

If the controller doesn't have an ID or if there's an ID collision.

Implementation

def add(controller)
	unless id = controller.id
		raise RuntimeError, "Controller must be registered with an ID before being added!"
	end
	
	if @controllers.key?(id)
		raise RuntimeError, "Controller already registered: id=#{id}"
	end
	
	@controllers[id] = controller
	
	# Notify chaos operations with the chaos controller:
	@chaos_operations.each do |chaos|
		chaos.register(controller)
	rescue => error
		Console.error(self, "Error while registering victim!", chaos: chaos, exception: error)
	end
end

def remove(controller)

Remove a victim connection from the chaos server.

Notifies all chaos operations and removes the connection from tracking.

Signature

parameter controller ChaosController

The controller to remove.

Implementation

def remove(controller)
	if id = controller.id
		@controllers.delete(id)
	end
	
	# Notify chaos operations with the chaos controller:
	@chaos_operations.each do |chaos|
		chaos.remove(controller)
	rescue => error
		Console.error(self, "Error while removing victim!", chaos: chaos, exception: error)
	end
end

def run

Run the chaos server.

Starts all chaos operations and accepts connections from victims.

Signature

parameter parent Async::Task

The parent task to run under.

Implementation

def run
	Sync do |task|
		# Start all chaos operations:
		@chaos_operations.each do |chaos|
			chaos.run
		rescue => error
			Console.error(self, "Error while starting chaos!", chaos: chaos, exception: error)
		end
		
		# Accept connections from victims:
		self.accept do |connection|
			# Create a chaos controller for this connection:
			chaos_controller = ChaosController.new(self, connection)
			
			# Bind chaos controller:
			connection.bind(:chaos, chaos_controller)
			
			# Run the connection:
			connection.run
		ensure
			self.remove(chaos_controller)
		end
		
		task.children&.each(&:wait)
	ensure
		task.stop
	end
end