Actor | Sent | Received | Send Rate | Receive Rate | Activity |
---|---|---|---|---|---|
alice | 12978 | 12967 | 4326.0 msg/s | 4322.33 msg/s | 25945 total |
bob | 13515 | 13504 | 4505.0 msg/s | 4501.33 msg/s | 27019 total |
charlie | 13325 | 13314 | 4441.67 msg/s | 4438.0 msg/s | 26639 total |
diana | 13366 | 13356 | 4455.33 msg/s | 4452.0 msg/s | 26722 total |
eve | 13107 | 13096 | 4369.0 msg/s | 4365.33 msg/s | 26203 total |
frank | 13090 | 13079 | 4363.33 msg/s | 4359.67 msg/s | 26169 total |
grace | 13277 | 13266 | 4425.67 msg/s | 4422.0 msg/s | 26543 total |
This is the Elixir code that defines the actor simulation model:
# Create 7 real GenServer actors that randomly send :hi messages
# Using VirtualTimeGenServer for virtual time support
defmodule HiActor do
use VirtualTimeGenServer
def start_link(name, targets, all_actors) do
initial_state = %{
name: name,
targets: targets,
all_actors: all_actors,
sent_count: 0,
received_count: 0
}
VirtualTimeGenServer.start_link(__MODULE__, initial_state, name: name)
end
def handle_info(:send_random_message, state) do
# Choose random target and send :hi
target = Enum.random(state.targets)
VirtualTimeGenServer.cast(target, {:hi, state.name})
# Schedule next message with random delay 200-300ms
delay = :rand.uniform(101) + 200
VirtualTimeGenServer.send_after(self(), :send_random_message, delay)
{:noreply, %{state | sent_count: state.sent_count + 1}}
end
def handle_cast({:hi, from}, state) do
# Simulate processing time for handling the message (50-150ms)
processing_delay = :rand.uniform(101) + 50
VirtualTimeGenServer.sleep(processing_delay)
# Received :hi, send random response
available_targets = Enum.reject(state.all_actors, &(&1 == from))
if length(available_targets) > 0 do
target = Enum.random(available_targets)
VirtualTimeGenServer.cast(target, {:hi, state.name})
end
{:noreply, %{state | received_count: state.received_count + 1}}
end
end
# Create simulation with real actors
all_actors = [:alice, :bob, :charlie, :diana, :eve, :frank, :grace]
simulation =
ActorSimulation.new(trace: true)
|> ActorSimulation.add_process(:alice,
module: HiActor,
args: [:alice, [:bob, :charlie, :diana, :eve, :frank, :grace], all_actors])
|> ActorSimulation.add_process(:bob,
module: HiActor,
args: [:bob, [:alice, :charlie, :diana, :eve, :frank, :grace], all_actors])
|> ActorSimulation.add_process(:charlie,
module: HiActor,
args: [:charlie, [:alice, :bob, :diana, :eve, :frank, :grace], all_actors])
|> ActorSimulation.add_process(:diana,
module: HiActor,
args: [:diana, [:alice, :bob, :charlie, :eve, :frank, :grace], all_actors])
|> ActorSimulation.add_process(:eve,
module: HiActor,
args: [:eve, [:alice, :bob, :charlie, :diana, :frank, :grace], all_actors])
|> ActorSimulation.add_process(:frank,
module: HiActor,
args: [:frank, [:alice, :bob, :charlie, :diana, :eve, :grace], all_actors])
|> ActorSimulation.add_process(:grace,
module: HiActor,
args: [:grace, [:alice, :bob, :charlie, :diana, :eve, :frank], all_actors])
|> ActorSimulation.run(duration: 3000)