class Yowl
Yowl causes random exceptions in victim processes.
Like a cat yowling in the night, this chaos operation randomly raises errors to test error handling and recovery.
Definitions
def initialize(interval: 45, probability: 0.15, messages: nil)
Create a new yowl chaos operation.
Signature
-
parameter
intervalInteger How often to check for chaos opportunities.
-
parameter
probabilityFloat Probability (0.0 to 1.0) of causing chaos on each check.
-
parameter
messagesArray<String> Possible error messages to use.
Implementation
def initialize(interval: 45, probability: 0.15, messages: nil)
@interval = interval
@probability = probability
@messages = messages || [
"Yowl! Chaos kitty is not pleased!",
"MEOWWWW! Something went wrong!",
"Hiss! An unexpected error occurred!",
"*Angry cat noises*",
"The chaos kitty demands tribute!"
]
@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 yowl chaos.
Signature
-
parameter
chaos_controllerChaosController The chaos controller for the victim.
Implementation
def register(chaos_controller)
Console.debug(self, "😺 Registering victim for yowl chaos.", id: chaos_controller.id)
@victims.add(chaos_controller)
end
def remove(chaos_controller)
Remove a victim from the yowl chaos.
Signature
-
parameter
chaos_controllerChaosController The chaos controller for the victim.
Implementation
def remove(chaos_controller)
@victims.delete(chaos_controller)
end
def status
Get status for the yowl chaos.
Signature
-
returns
Hash Status including victim count and configuration.
Implementation
def status
{
yowl: {
victims: @victims.size,
probability: @probability,
message_variants: @messages.size
}
}
end
def unleash_yowl
Unleash a yowl on a random victim.
Implementation
def unleash_yowl
return if @victims.empty?
# Pick a random victim
victim = @victims.to_a.sample
return unless victim
# Check probability
return unless rand < @probability
# Pick a random message
message = @messages.sample
Console.info(self, "😾 *YOWWWWL* Error incoming!", id: victim.id, message: message)
begin
victim_proxy = victim.connection[:victim]
if victim_proxy
victim_proxy.raise_error(message: message)
end
rescue => error
# This is expected - we're causing an error!
Console.debug(self, "Yowl successful (error was raised)!", id: victim.id)
end
end
def run
Run the yowl chaos operation.
Signature
-
returns
Async::Task The task that is running the yowl chaos.
Implementation
def run
Async do
Loop.run(interval: @interval) do
unleash_yowl
end
end
end