| Actor | Sent | Received | Send Rate | Receive Rate | Activity |
|---|---|---|---|---|---|
| alice | 5772 | 5761 | 1924.0 msg/s | 1920.33 msg/s | 11533 total |
| bob | 5938 | 5927 | 1979.33 msg/s | 1975.67 msg/s | 11865 total |
| charlie | 6282 | 6270 | 2094.0 msg/s | 2090.0 msg/s | 12552 total |
| diana | 6001 | 5990 | 2000.33 msg/s | 1996.67 msg/s | 11991 total |
| eve | 5965 | 5954 | 1988.33 msg/s | 1984.67 msg/s | 11919 total |
| frank | 5882 | 5871 | 1960.67 msg/s | 1957.0 msg/s | 11753 total |
| grace | 5859 | 5848 | 1953.0 msg/s | 1949.33 msg/s | 11707 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 available_targets != [] 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)