···337337 end
338338 end
339339340340+ def list_nodes do
341341+ if not simulated?(), do: raise "list_nodes/0 can only be called in simulation"
342342+ scheduler_pid = fetch_scheduler_pid!()
343343+344344+ Scheduler.list_nodes(scheduler_pid)
345345+ end
346346+340347 @spec start_node(atom, module, term) :: :ok
341348 def start_node(name, app_module, args) when is_atom(name) and is_atom(app_module) do
342349 if not simulated?(), do: raise "start_node/3 can only be called in simulation"
343350 scheduler_pid = fetch_scheduler_pid!()
344351345352 Scheduler.start_node(scheduler_pid, name, app_module, args)
353353+ end
354354+355355+ def restart_node(name, delay_ms \\ 0) when is_atom(name) and is_integer(delay_ms) do
356356+ if not simulated?(), do: raise "restart_node/1 can only be called in simulation"
357357+ scheduler_pid = fetch_scheduler_pid!()
358358+359359+ Scheduler.restart_node(scheduler_pid, name, delay_ms)
346360 end
347361348362 @spec monitor(pid) :: reference
+6-8
lib/servers/coordinator.ex
···347347 state = update_view(state, state.view_number)
348348 state = save_state_and_commit(state)
349349350350- state =
351351- case state.role do
352352- :primary -> start_new_manager(state)
353353- _ -> state
354354- end
350350+ state = start_manager_if_primary(state)
355351356352 SimServer.send_after(self(), :tick, @tick_interval_ms)
357353···443439 true ->
444440 state =
445441 %{state | manager_pid: nil, manager_generation: nil}
446446- |> start_new_manager()
442442+ |> start_manager_if_primary()
447443448444 {:noreply, state}
449445···856852857853 state
858854 |> send_start_view(other_replica_pids(state))
859859- |> start_new_manager()
855855+ |> start_manager_if_primary()
860856 end
861857862858 defp on_request_start_view(%State{} = state, %RequestStartView{} = rsv) when rsv.view_number != state.view_number do
···1117111311181114 # Hobbes/Cluster
1119111511201120- defp start_new_manager(%State{} = state) do
11161116+ defp start_manager_if_primary(%State{role: :backup} = state), do: state
11171117+11181118+ defp start_manager_if_primary(%State{} = state) do
11211119 assert state.role == :primary
11221120 assert state.manager_pid == nil
11231121 assert state.manager_generation == nil
+6-1
lib/servers/distributor.ex
···157157 |> Enum.chunk_every(2, 1, :discard)
158158 |> Enum.map(fn [{start_key, from, _to}, {end_key, _, _}] ->
159159 from
160160- |> Enum.map(fn id -> Map.get(state.storage_servers, id).pid end)
160160+ |> Enum.map(fn id ->
161161+ case Map.fetch(state.storage_servers, id) do
162162+ {:ok, %StorageInfo{pid: pid}} -> pid
163163+ :error -> nil
164164+ end
165165+ end)
161166 |> Enum.reject(&is_nil/1)
162167 |> case do
163168 [_ | _] = from_pids ->
+28
lib/workloads/restart_nodes.ex
···11+defmodule Hobbes.Workloads.RestartNodes do
22+ alias Hobbes.Construct.SimServer
33+44+ @behaviour Hobbes.Workloads.Workload
55+66+ defp restart_random_node do
77+ nodes = SimServer.list_nodes()
88+ #node = Enum.random(nodes)
99+ node = hd(nodes)
1010+1111+ result = SimServer.restart_node(node, 4000)
1212+ {node, result}
1313+ end
1414+1515+ def run(%{}, opts) do
1616+ delay = Keyword.get(opts, :delay, 3000)
1717+1818+ SimServer.sleep(delay)
1919+ result = restart_random_node()
2020+2121+ {
2222+ :ok,
2323+ """
2424+ Result: #{inspect(result)}
2525+ """,
2626+ }
2727+ end
2828+end