Async::Service::ChaosKittySourceAsyncServiceChaosKittyHairball

class Hairball

Hairball causes random delays and blocking in victim processes.

Like a cat hacking up a hairball, this chaos operation randomly blocks victims, simulating slow responses or stuck operations.

Definitions

def initialize(interval: 30, probability: 0.3, min_delay: 0.5, max_delay: 5.0)

Create a new hairball chaos operation.

Signature

parameter interval Integer

How often to check for chaos opportunities.

parameter probability Float

Probability (0.0 to 1.0) of causing chaos on each check.

parameter min_delay Numeric

Minimum delay duration in seconds.

parameter max_delay Numeric

Maximum delay duration in seconds.

Implementation

def initialize(interval: 30, probability: 0.3, min_delay: 0.5, max_delay: 5.0)
	@interval = interval
	@probability = probability
	@min_delay = min_delay
	@max_delay = max_delay
	@victims = Set.new.compare_by_identity
end

attr_reader :victims

Signature

attribute Set

The set of registered victims.

def register(chaos_controller)

Register a victim with the hairball chaos.

Signature

parameter chaos_controller ChaosController

The chaos controller for the victim.

Implementation

def register(chaos_controller)
	Console.debug(self, "😺 Registering victim for hairball chaos.", id: chaos_controller.id)
	@victims.add(chaos_controller)
end

def remove(chaos_controller)

Remove a victim from the hairball chaos.

Signature

parameter chaos_controller ChaosController

The chaos controller for the victim.

Implementation

def remove(chaos_controller)
	@victims.delete(chaos_controller)
end

def status

Get status for the hairball chaos.

Signature

returns Hash

Status including victim count and configuration.

Implementation

def status
	{
		hairball: {
			victims: @victims.size,
			probability: @probability,
			delay_range: [@min_delay, @max_delay]
		}
	}
end

def unleash_hairball

Unleash a hairball on a random victim.

Implementation

def unleash_hairball
	return if @victims.empty?
	
	# Pick a random victim
	victim = @victims.to_a.sample
	return unless victim
	
	# Check probability
	return unless rand < @probability
	
	# Calculate random delay
	delay = @min_delay + rand * (@max_delay - @min_delay)
	
	Console.info(self, "😾 *HACK* *HACK* Hairball time!", id: victim.id, delay: delay)
	
	begin
		victim_proxy = victim.connection[:victim]
		if victim_proxy
			victim_proxy.delay(duration: delay)
		end
	rescue => error
		Console.error(self, "Failed to unleash hairball!", id: victim.id, exception: error)
	end
end

def run

Run the hairball chaos operation.

Signature

returns Async::Task

The task that is running the hairball chaos.

Implementation

def run
	Async do
		Loop.run(interval: @interval) do
			unleash_hairball
		end
	end
end