diff --git a/lib/trinity/scheduler/simulation_supervisor.ex b/lib/trinity/scheduler/simulation_supervisor.ex index 36d7253..3226faf 100644 --- a/lib/trinity/scheduler/simulation_supervisor.ex +++ b/lib/trinity/scheduler/simulation_supervisor.ex @@ -10,7 +10,8 @@ defmodule Trinity.Scheduler.SimulationSupervisor do :root_pid, :parent_pid, - :parent_ref, + :ref, + :result, ] defstruct @enforce_keys end @@ -22,14 +23,14 @@ defmodule Trinity.Scheduler.SimulationSupervisor do seed: seed, fun: fun, parent_pid: self(), - parent_ref: ref, + ref: ref, }) receive do - {^ref, :normal} -> :ok - {^ref, :shutdown} -> :ok + {^ref, :normal, result} -> result + {^ref, :shutdown, result} -> result # Propagate root exit to parent process so tests fail - {^ref, reason} -> exit(reason) + {^ref, reason, _result} -> exit(reason) end end @@ -38,7 +39,7 @@ defmodule Trinity.Scheduler.SimulationSupervisor do GenServer.call(server, {:spawn_child, fun}) end - def init(%{seed: seed, fun: fun, parent_pid: parent_pid, parent_ref: parent_ref}) do + def init(%{seed: seed, fun: fun, parent_pid: parent_pid, ref: ref}) do Process.flag(:trap_exit, true) :rand.seed(:exsss, seed) @@ -64,11 +65,13 @@ defmodule Trinity.Scheduler.SimulationSupervisor do :ets.insert(sim.file_paths, {:next_fd, 0}) + supervisor_pid = sim.supervisor_pid # TODO: configurable? root_node = :nonode root_pid = spawn_sim_child(sim, fn -> Trinity.Scheduler.set_up_root(root_node) - fun.() + result = fun.() + send supervisor_pid, {ref, result} end) state = %State{ @@ -76,7 +79,8 @@ defmodule Trinity.Scheduler.SimulationSupervisor do root_pid: root_pid, parent_pid: parent_pid, - parent_ref: parent_ref, + ref: ref, + result: nil, } {:ok, state} @@ -87,6 +91,10 @@ defmodule Trinity.Scheduler.SimulationSupervisor do {:reply, pid, state} end + def handle_info({ref, result}, %State{} = state) when ref == state.ref do + {:noreply, %{state | result: result}} + end + def handle_info({:EXIT, from, reason}, %State{} = state) do %State{ root_pid: root_pid, @@ -115,7 +123,7 @@ defmodule Trinity.Scheduler.SimulationSupervisor do end defp end_simulation(%State{} = state, reason) do - %{sim: sim, parent_pid: parent_pid, parent_ref: parent_ref} = state + %{sim: sim, parent_pid: parent_pid, ref: ref, result: result} = state %Simulation{log: log, log_atomic: log_atomic} = sim hash = :atomics.get(log_atomic, 1) @@ -129,7 +137,7 @@ defmodule Trinity.Scheduler.SimulationSupervisor do #{print_log(log)} """ - send parent_pid, {parent_ref, reason} + send parent_pid, {ref, reason, result} end defp print_hash(hash) do diff --git a/test/trinity_test.exs b/test/trinity_test.exs index 60bd16c..834c6f7 100644 --- a/test/trinity_test.exs +++ b/test/trinity_test.exs @@ -53,7 +53,7 @@ defmodule TrinityTest do end test "scheduler" do - Sim.run_simulation(fn -> + result = Sim.run_simulation(fn -> nodes = [:n1, :n2, :n3] pids = Enum.map(nodes, fn node -> @@ -98,6 +98,9 @@ defmodule TrinityTest do Scheduler.yield(1000) #dbg Scheduler.dump(), limit: :infinity + :success end, seed: 101) + + assert result == :success end end