···129129 ref
130130 end
131131132132+ @spec alias(pid) :: reference
133133+ def alias(scheduler) do
134134+ GenServer.call(scheduler, {:alias, self()})
135135+ end
136136+137137+ @spec unalias(pid, reference) :: boolean
138138+ def unalias(scheduler, alias) when is_reference(alias) do
139139+ GenServer.call(scheduler, {:unalias, self(), alias})
140140+ end
141141+132142 @spec set_process_flag(pid, :trap_exit, boolean) :: :ok
133143 def set_process_flag(scheduler, :trap_exit = flag, value) when is_boolean(value) do
134144 {:ok, old_value} = GenServer.call(scheduler, {:set_process_flag, self(), flag, value})
···176186177187 state = set_current_process(state, initial_pid)
178188 {:ok, state}
189189+ end
190190+191191+ def handle_call({:alias, pid}, _from, %State{} = state) do
192192+ alias = make_ref()
193193+ ProcStore.add_alias(state.proc_store, pid, alias)
194194+ {:reply, alias, state}
195195+ end
196196+197197+ def handle_call({:unalias, pid, alias}, _from, %State{} = state) do
198198+ case ProcStore.remove_alias(state.proc_store, pid, alias) do
199199+ :ok -> {:reply, true, state}
200200+ {:error, _err} -> {:reply, false, state}
201201+ end
179202 end
180203181204 def handle_call({:set_process_flag, pid, flag, value}, _from, %State{} = state) do
···440463 {:ok, pid} -> pid
441464 {:error, :not_found} -> nil
442465 end
466466+467467+ alias when is_reference(alias) ->
468468+ case ProcStore.resolve_alias(state.proc_store, alias) do
469469+ {:ok, pid} -> pid
470470+ :error -> nil
471471+ end
472472+443473 pid when is_pid(pid) -> pid
444474 end
445475
+30-1
lib/construct/scheduler/proc_store.ex
···2828 proc_table: :ets.table,
2929 }
30303131- @enforce_keys [:proc_table]
3131+ @enforce_keys [:proc_table, :alias_table]
3232 defstruct @enforce_keys
33333434 def new do
3535 %ProcStore{
3636 proc_table: :ets.new(:proc_table, [:set, :private]),
3737+ alias_table: :ets.new(:alias_table, [:set, :private]),
3738 }
3839 end
3940···171172 :ets.insert(ps.proc_table, {pid, %{proc_state | monitors: monitors}})
172173 :ets.insert(ps.proc_table, {target_pid, %{target_state | monitored_by: monitored_by}})
173174 :ok
175175+ end
176176+177177+ @spec add_alias(t, pid, reference) :: :ok
178178+ def add_alias(%ProcStore{} = ps, pid, alias) when is_pid(pid) and is_reference(alias) do
179179+ :ets.insert(ps.alias_table, {alias, pid})
180180+ :ok
181181+ end
182182+183183+ @spec remove_alias(t, pid, reference) :: :ok | {:error, :wrong_process | :not_found}
184184+ def remove_alias(%ProcStore{} = ps, pid, alias) when is_pid(pid) and is_reference(alias) do
185185+ case resolve_alias(ps, alias) do
186186+ {:ok, ^pid} ->
187187+ :ets.delete(ps.alias_table, alias)
188188+ :ok
189189+190190+ {:ok, _other} -> {:error, :wrong_process}
191191+ :error -> {:error, :not_found}
192192+ end
193193+ end
194194+195195+ @spec resolve_alias(t, reference) :: {:ok, pid} | :error
196196+ def resolve_alias(%ProcStore{} = ps, alias) when is_reference(alias) do
197197+ case :ets.lookup(ps.alias_table, alias) do
198198+ [{^alias, pid}] when is_pid(pid) ->
199199+ {:ok, pid}
200200+ [] ->
201201+ :error
202202+ end
174203 end
175204176205 @spec set_flag(t, pid, :trap_exit, boolean) :: {:ok, boolean}
+2-2
lib/construct/sim_internal.ex
···4545 sim_loop(module, state)
4646 end
47474848- defp dispatch({:"$sim_call", {client_pid, ref} = from, request}, module, state) do
4848+ defp dispatch({:"$sim_call", {_pid, [:alias | alias_ref] = tag} = from, request}, module, state) do
4949 try do
5050 module.handle_call(request, from, state)
5151 catch
···5555 end
5656 |> case do
5757 {:reply, response, state} ->
5858- SimServer.send client_pid, {ref, response}
5858+ SimServer.send alias_ref, {tag, response}
5959 state
6060 {:noreply, state} ->
6161 state
+5
lib/construct/sim_log.ex
···9696 end
9797 end
98989999+ defp homogenize(%Known{} = known, [:alias | ref]) when is_reference(ref) do
100100+ {known, h_ref} = homogenize(known, ref)
101101+ {known, [:alias | h_ref]}
102102+ end
103103+99104 defp homogenize(%Known{} = known, list) when is_list(list) do
100105 {known, h_list} = Enum.reduce(list, {known, []}, fn element, {known, acc_list} ->
101106 {k, h_el} = homogenize(known, element)
+24-11
lib/construct/sim_server.ex
···196196 end
197197198198 defp sim_call(scheduler_pid, server, request, timeout) do
199199- request_id = sim_send_request(scheduler_pid, server, request)
199199+ alias_ref = sim_send_request(scheduler_pid, server, request)
200200+200201 try do
201202 yield_receive(scheduler_pid, timeout) do
202202- {^request_id, reply} -> reply
203203+ {[:alias | ^alias_ref], reply} -> reply
203204 end
204205 catch
205206 :exit, reason ->
206206- exit({reason, {__MODULE__, :call, [server, request, timeout]}})
207207+ true = Scheduler.unalias(scheduler_pid, alias_ref)
208208+ receive do
209209+ {[:alias | ^alias_ref], reply} -> reply
210210+ after
211211+ 0 -> exit({reason, {__MODULE__, :call, [server, request, timeout]}})
212212+ end
207213 end
208214 end
209215216216+ @dialyzer {:no_improper_lists, sim_send_request: 3}
210217 defp sim_send_request(scheduler_pid, server, request) do
211211- ref = make_ref()
212212- Scheduler.send(scheduler_pid, server, {:"$sim_call", {self(), ref}, request})
218218+ alias_ref = Scheduler.alias(scheduler_pid)
219219+ Scheduler.send(scheduler_pid, server, {:"$sim_call", {self(), [:alias | alias_ref]}, request})
213220214214- ref
221221+ alias_ref
215222 end
216223217224 defp sim_receive_response(scheduler_pid, request_id, timeout) when is_reference(request_id) do
225225+ alias_ref = request_id
218226 # TODO: catch timeout exit
219227 try do
220228 yield_receive(scheduler_pid, timeout) do
221221- {^request_id, reply} -> {:reply, reply}
229229+ {[:alias | ^alias_ref], reply} -> {:reply, reply}
222230 end
223231 catch
224224- :exit, _reason ->
225225- :timeout
232232+ :exit, :timeout ->
233233+ true = Scheduler.unalias(scheduler_pid, alias_ref)
234234+ receive do
235235+ {[:alias | ^alias_ref], reply} -> {:reply, reply}
236236+ after
237237+ 0 -> :timeout
238238+ end
226239 end
227240 end
228241···257270 GenServer.reply(client, response)
258271259272 scheduler_pid when is_pid(scheduler_pid) ->
260260- {client_pid, ref} = client
261261- Scheduler.send(scheduler_pid, client_pid, {ref, response})
273273+ {_client_pid, [:alias | alias_ref] = tag} = client
274274+ Scheduler.send(scheduler_pid, alias_ref, {tag, response})
262275 :ok
263276 end
264277 end
-2
lib/servers/distributor.ex
···128128 end
129129 end
130130131131- def handle_info(_message, %State{} = state), do: {:noreply, state}
132132-133131 defp scan_shards(%State{} = state) when state.cluster.status != :normal do
134132 state
135133 end
-2
lib/workloads/cycle.ex
···6666 {:noreply, state}
6767 end
68686969- def handle_info(_message, %State{} = state), do: {:noreply, state}
7070-7169 defp work(%State{} = state) do
7270 state = inc_stat(state, :swaps)
7371