···258258 :ok
259259 end
260260261261+ def handle_kill_node(node, from_pid) do
262262+ %{node_procs: node_procs} = sim = get_sim()
263263+ [{_node, pids}] = :ets.lookup(node_procs, node)
264264+ dbg pids
265265+266266+ # Note: we can ignore links here because we currently only support links on the same node
267267+ Enum.each(pids, fn pid ->
268268+ # Killing a node from within the node is not currently allowed
269269+ # TODO: maybe allow this?
270270+ assert pid != from_pid
271271+ destroy_process(sim, pid)
272272+273273+ assert Process.alive?(pid)
274274+ Process.exit(pid, :kill)
275275+276276+ receive do
277277+ {:EXIT, ^pid, _reason} -> :noop
278278+ end
279279+ end)
280280+ end
281281+261282 defp destroy_or_message_linked(%Simulation{} = sim, for_pid, reason, visited) do
262283 linked =
263284 case :ets.lookup(sim.proc_links, for_pid) do
+9
lib/trinity/scheduler/simulation_supervisor.ex
···3939 GenServer.call(server, {:spawn_child, fun})
4040 end
41414242+ def kill_node(server, node) do
4343+ GenServer.call(server, {:kill_node, node, self()})
4444+ end
4545+4246 def init(%{seed: seed, fun: fun, parent_pid: parent_pid, ref: ref}) do
4347 Process.flag(:trap_exit, true)
4448 :rand.seed(:exsss, seed)
···8993 def handle_call({:spawn_child, fun}, _from, %State{} = state) do
9094 pid = spawn_sim_child(state.sim, fun)
9195 {:reply, pid, state}
9696+ end
9797+9898+ def handle_call({:kill_node, node, from_pid}, _from, %State{} = state) do
9999+ Trinity.Scheduler.handle_kill_node(node, from_pid)
100100+ {:reply, :ok, state}
92101 end
9310294103 def handle_info({ref, result}, %State{} = state) when ref == state.ref do
+16
lib/trinity/sim.ex
···1212 Trinity.Scheduler.SimulationSupervisor.run_simulation(fun, %{seed: seed})
1313 end
14141515+ @spec list_nodes :: [atom]
1616+ def list_nodes do
1717+ %{node_procs: node_procs} = get_sim()
1818+ :ets.tab2list(node_procs)
1919+ |> Enum.map(fn {node, _pids} -> node end)
2020+ |> Enum.reject(&(&1 == :nonode))
2121+ |> Enum.sort()
2222+ end
2323+2424+ @spec kill_node(atom) :: :ok
2525+ def kill_node(node) do
2626+ %{supervisor_pid: supervisor_pid} = get_sim()
2727+ Trinity.Scheduler.SimulationSupervisor.kill_node(supervisor_pid, node)
2828+ :ok
2929+ end
3030+1531 @spec simulated? :: boolean
1632 def simulated? do
1733 case get_sim() do