Real Actors - VirtualTimeGenServer

Generated by GenServerVirtualTime โ€ข Mermaid Flowchart

๐Ÿ“ˆ Simulation Summary

Virtual Time
3000ms
Real Time
64ms
Speedup
46.9x
Termination
โฑ Max Time

๐Ÿ“Š Actor Topology

flowchart LR alice("alice
๐Ÿ“ค Sent: 5772
๐Ÿ“ฅ Recv: 5761") bob("bob
๐Ÿ“ค Sent: 5938
๐Ÿ“ฅ Recv: 5927") charlie("charlie
๐Ÿ“ค Sent: 6282
๐Ÿ“ฅ Recv: 6270") diana("diana
๐Ÿ“ค Sent: 6001
๐Ÿ“ฅ Recv: 5990") eve("eve
๐Ÿ“ค Sent: 5965
๐Ÿ“ฅ Recv: 5954") frank("frank
๐Ÿ“ค Sent: 5882
๐Ÿ“ฅ Recv: 5871") grace("grace
๐Ÿ“ค Sent: 5859
๐Ÿ“ฅ Recv: 5848") frank -->|:message| diana eve -->|:message| charlie grace -->|:message| charlie diana -->|:message| frank diana -->|:message| eve charlie -->|:message| grace frank -->|:message| bob alice -->|:message| charlie bob -->|:message| eve eve -->|:message| frank bob -->|:message| alice eve -->|:message| alice charlie -->|:message| eve charlie -->|:message| diana eve -->|:message| bob grace -->|:message| frank grace -->|:message| bob diana -->|:message| alice frank -->|:message| alice frank -->|:message| grace bob -->|:message| frank alice -->|:message| diana bob -->|:message| diana diana -->|:message| bob grace -->|:message| eve grace -->|:message| alice alice -->|:message| eve charlie -->|:message| alice diana -->|:message| grace frank -->|:message| eve frank -->|:message| charlie charlie -->|:message| bob bob -->|:message| grace alice -->|:message| bob charlie -->|:message| frank eve -->|:message| diana grace -->|:message| diana alice -->|:message| grace alice -->|:message| frank eve -->|:message| grace bob -->|:message| charlie diana -->|:message| charlie style alice fill:#fff3e0,stroke:#f57c00,stroke-width:3px style bob fill:#fff3e0,stroke:#f57c00,stroke-width:3px style charlie fill:#fff3e0,stroke:#f57c00,stroke-width:3px style diana fill:#fff3e0,stroke:#f57c00,stroke-width:3px style eve fill:#fff3e0,stroke:#f57c00,stroke-width:3px style frank fill:#fff3e0,stroke:#f57c00,stroke-width:3px style grace fill:#fff3e0,stroke:#f57c00,stroke-width:3px

Node Shapes (Actor Type)

flowchart TD legend_processor("Processor
(send & receive)") style legend_processor fill:#ffffff,stroke:#666666,stroke-width:2px

Node Colors (Activity Level)

flowchart LR activity_0["๐ŸŸ  High Activity (>50 msgs)"] style activity_0 fill:#fff3e0,stroke:#f57c00,stroke-width:3px

๐Ÿ“‰ Detailed Statistics

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
Summary: Total messages: 83320 โ€ข Duration: 3000ms โ€ข Actors: 7

๐Ÿ’ป Model Source Code

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)