···149149 GenServer.call(scheduler, {:register_process, self(), pid, name})
150150 end
151151152152+ def whereis(scheduler, name) when is_atom(name) do
153153+ GenServer.call(scheduler, {:whereis, self(), name})
154154+ end
155155+152156 @spec get_file_store(pid) :: FileStore.t
153157 def get_file_store(scheduler) do
154158 GenServer.call(scheduler, {:get_file_store, self()})
···216220 {:reply, :ok, state}
217221 {:error, _error} ->
218222 {:reply, :error, state}
223223+ end
224224+ end
225225+226226+ def handle_call({:whereis, _from_pid, name}, _from, %State{} = state) do
227227+ # TODO: use node of from_pid
228228+ node = :nonode
229229+230230+ case ProcRegistry.whereis(state.proc_registry, node, name) do
231231+ {:ok, pid} -> {:reply, pid, state}
232232+ {:error, :not_found} -> {:reply, nil, state}
219233 end
220234 end
221235···406420407421 case ProcStore.fetch_state(state.proc_store, exit.to_pid) do
408422 {:ok, %ProcState{} = proc} ->
409409- case proc.trap_exit do
423423+ case proc.trap_exit and exit.reason != :kill do
410424 true ->
411425 state
412426 |> send_message(%Send{dest: proc.pid, message: {:EXIT, exit.from_pid, exit.reason}})
+10
lib/construct/sim_server.ex
···370370 end
371371 end
372372373373+ @spec whereis(atom) :: pid | nil
374374+ def whereis(name) do
375375+ case get_scheduler_pid() do
376376+ scheduler_pid when is_pid(scheduler_pid) ->
377377+ Scheduler.whereis(scheduler_pid, name)
378378+ nil ->
379379+ Process.whereis(name)
380380+ end
381381+ end
382382+373383 @doc """
374384 Returns a monotonic microsecond timestamp.
375385
+5-2
lib/servers/coordinator.ex
···187187 @spec request(server, {module, atom, list}) :: term | request_error
188188 def request(server, {m, f, a} = command) when is_atom(m) and is_atom(f) and is_list(a) do
189189 try do
190190- SimServer.call(server, {:request, command})
190190+ SimServer.call(server, {:request, command}, 1000)
191191 catch
192192 :exit, {:timeout, _mfa} -> {:error, :timeout}
193193 end
···445445446446 {:noreply, state}
447447448448- false -> {:noreply, state}
448448+ # TODO: get rid of this once we have a proper supervision tree
449449+ # (for now we need to be able to kill coordinators for testing)
450450+ false -> exit(:normal)
451451+ #false -> {:noreply, state}
449452 end
450453 end
451454
+7-2
lib/workloads/coordinator_read_write.ex
···6868 do
6969 %State{} = state
7070 else
7171- {:error, :timeout} -> inc(state, :timeout)
7272- {:error, {:not_primary, new_primary}} -> %{state | current_coordinator: new_primary} |> inc(:not_primary)
7171+ {:error, :timeout} ->
7272+ # Current coordinator is not responding, try another one
7373+ new_coordinator = List.delete(state.cluster.coordinators, state.current_coordinator) |> Enum.random()
7474+ %{state | current_coordinator: new_coordinator} |> inc(:timeout)
7575+7676+ {:error, {:not_primary, new_primary}} ->
7777+ %{state | current_coordinator: new_primary} |> inc(:not_primary)
7378 end
7479 end
7580
+14-1
lib/workloads/kill_servers.ex
···1010 def run(%{cluster: %Cluster{} = cluster}, opts) do
1111 delay_ms = Keyword.get(opts, :delay_ms, 0)
1212 duration_ms = Keyword.get(opts, :duration_ms, 0)
1313+ server_type = Keyword.get(opts, :server_type, Hobbes.Servers.TLog)
13141415 SimServer.sleep(delay_ms)
15161616- %Server{pid: kill_pid} = get_servers(cluster, Hobbes.Servers.TLog) |> hd()
1717+ kill_pid =
1818+ case server_type do
1919+ Hobbes.Servers.Coordinator ->
2020+ hd(cluster.coordinators)
2121+ |> case do
2222+ pid when is_pid(pid) -> pid
2323+ name when is_atom(name) -> SimServer.whereis(name)
2424+ end
2525+ other ->
2626+ %Server{pid: pid} = get_servers(cluster, other) |> hd()
2727+ pid
2828+ end
2929+1730 SimServer.exit(kill_pid, :shutdown)
18311932 SimServer.sleep(duration_ms)