this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Refactor ProcStore to use struct

+52 -45
+52 -45
lib/construct/scheduler/proc_store.ex
··· 1 1 defmodule Hobbes.Construct.Scheduler.ProcStore do 2 - alias Hobbes.Construct.Scheduler.ProcQueue 2 + alias Hobbes.Construct.Scheduler.{ProcStore, ProcQueue} 3 3 4 4 @type check_fun :: (-> boolean) 5 5 ··· 24 24 ] ++ @enforce_keys 25 25 end 26 26 27 - @type t :: :ets.table 27 + @type t :: %__MODULE__{ 28 + proc_table: :ets.table, 29 + } 30 + 31 + @enforce_keys [:proc_table] 32 + defstruct @enforce_keys 28 33 29 34 def new do 30 - :ets.new(:proc_store, [:set, :private]) 35 + %ProcStore{ 36 + proc_table: :ets.new(:proc_table, [:set, :private]), 37 + } 31 38 end 32 39 33 40 @spec add_process(t, pid) :: :ok 34 - def add_process(table, pid) when is_pid(pid) do 41 + def add_process(%ProcStore{} = ps, pid) when is_pid(pid) do 35 42 state = %ProcState{pid: pid} 36 43 37 - :ets.insert(table, {pid, state}) 44 + :ets.insert(ps.proc_table, {pid, state}) 38 45 :ok 39 46 end 40 47 41 48 @spec remove_process(t, pid) :: :ok 42 - def remove_process(table, pid) when is_pid(pid) do 43 - case fetch_state(table, pid) do 49 + def remove_process(%ProcStore{} = ps, pid) when is_pid(pid) do 50 + case fetch_state(ps, pid) do 44 51 {:ok, _proc} -> 45 - :ets.delete(table, pid) 52 + :ets.delete(ps.proc_table, pid) 46 53 :ok 47 54 :error -> 48 55 raise "Process #{inspect(pid)} cannot be removed because it does not exist" ··· 50 57 end 51 58 52 59 @spec fetch_state(t, pid) :: {:ok, ProcState.t} | :error 53 - def fetch_state(table, pid) when is_pid(pid) do 54 - case :ets.lookup(table, pid) do 60 + def fetch_state(%ProcStore{} = ps, pid) when is_pid(pid) do 61 + case :ets.lookup(ps.proc_table, pid) do 55 62 [{^pid, %ProcState{} = state}] -> 56 63 {:ok, state} 57 64 _ -> ··· 60 67 end 61 68 62 69 @spec track_queued(t, pid, ProcQueue.key) :: :ok 63 - def track_queued(table, pid, {_, _} = queue_key) when is_pid(pid) do 64 - {:ok, %ProcState{} = state} = fetch_state(table, pid) 70 + def track_queued(%ProcStore{} = ps, pid, {_, _} = queue_key) when is_pid(pid) do 71 + {:ok, %ProcState{} = state} = fetch_state(ps, pid) 65 72 if state.queue_key != nil, do: raise "Process is already in queue: #{inspect(state)}" 66 73 67 74 state = %{state | queue_key: queue_key} 68 - :ets.insert(table, {pid, state}) 75 + :ets.insert(ps.proc_table, {pid, state}) 69 76 :ok 70 77 end 71 78 72 79 @spec clear_queued(t, pid) :: :ok 73 - def clear_queued(table, pid) do 74 - {:ok, %ProcState{} = state} = fetch_state(table, pid) 80 + def clear_queued(%ProcStore{} = ps, pid) do 81 + {:ok, %ProcState{} = state} = fetch_state(ps, pid) 75 82 76 - :ets.insert(table, {pid, %{state | queue_key: nil}}) 83 + :ets.insert(ps.proc_table, {pid, %{state | queue_key: nil}}) 77 84 :ok 78 85 end 79 86 80 87 @spec track_await(t, pid, check_fun, term, ProcQueue.key | nil) :: :ok 81 - def track_await(table, pid, check_fun, resume, timeout_queue_key) 88 + def track_await(%ProcStore{} = ps, pid, check_fun, resume, timeout_queue_key) 82 89 when is_pid(pid) and is_function(check_fun) and is_struct(resume) and (is_nil(timeout_queue_key) or is_tuple(timeout_queue_key)) do 83 - {:ok, %ProcState{} = state} = fetch_state(table, pid) 90 + {:ok, %ProcState{} = state} = fetch_state(ps, pid) 84 91 if state.queue_key != nil, do: raise "Process is in queue: #{inspect(state)}" 85 92 86 93 state = %{state | await: {check_fun, resume}, queue_key: timeout_queue_key} 87 - :ets.insert(table, {pid, state}) 94 + :ets.insert(ps.proc_table, {pid, state}) 88 95 :ok 89 96 end 90 97 91 98 @spec clear_await(t, pid) :: :ok 92 - def clear_await(table, pid) do 93 - {:ok, %ProcState{} = state} = fetch_state(table, pid) 99 + def clear_await(%ProcStore{} = ps, pid) do 100 + {:ok, %ProcState{} = state} = fetch_state(ps, pid) 94 101 if !state.await, do: raise "Process is not awaiting: #{inspect(state)}" 95 102 96 103 state = %{state | await: nil, queue_key: nil} 97 - :ets.insert(table, {pid, state}) 104 + :ets.insert(ps.proc_table, {pid, state}) 98 105 :ok 99 106 end 100 107 101 108 @spec add_link(t, pid, pid) :: :ok | :error 102 - def add_link(table, pid1, pid2) do 103 - {:ok, %ProcState{} = state1} = fetch_state(table, pid1) 104 - {:ok, %ProcState{} = state2} = fetch_state(table, pid2) 109 + def add_link(%ProcStore{} = ps, pid1, pid2) do 110 + {:ok, %ProcState{} = state1} = fetch_state(ps, pid1) 111 + {:ok, %ProcState{} = state2} = fetch_state(ps, pid2) 105 112 106 113 case pid2 in state1.linked_to do 107 114 false -> 108 115 state1 = Map.update!(state1, :linked_to, &[pid2 | &1]) 109 116 state2 = Map.update!(state2, :linked_to, &[pid1 | &1]) 110 117 111 - :ets.insert(table, {pid1, state1}) 112 - :ets.insert(table, {pid2, state2}) 118 + :ets.insert(ps.proc_table, {pid1, state1}) 119 + :ets.insert(ps.proc_table, {pid2, state2}) 113 120 :ok 114 121 115 122 true -> :error ··· 117 124 end 118 125 119 126 @spec remove_link(t, pid, pid) :: :ok | :error 120 - def remove_link(table, pid1, pid2) do 121 - {:ok, %ProcState{} = state1} = fetch_state(table, pid1) 122 - {:ok, %ProcState{} = state2} = fetch_state(table, pid2) 127 + def remove_link(%ProcStore{} = ps, pid1, pid2) do 128 + {:ok, %ProcState{} = state1} = fetch_state(ps, pid1) 129 + {:ok, %ProcState{} = state2} = fetch_state(ps, pid2) 123 130 124 131 case pid2 in state1.linked_to do 125 132 true -> 126 133 state1 = Map.update!(state1, :linked_to, &List.delete(&1, pid2)) 127 134 state2 = Map.update!(state2, :linked_to, &List.delete(&1, pid1)) 128 135 129 - :ets.insert(table, {pid1, state1}) 130 - :ets.insert(table, {pid2, state2}) 136 + :ets.insert(ps.proc_table, {pid1, state1}) 137 + :ets.insert(ps.proc_table, {pid2, state2}) 131 138 :ok 132 139 133 140 false -> :error ··· 135 142 end 136 143 137 144 @spec add_monitor(t, pid, pid, reference) :: :ok 138 - def add_monitor(table, pid, target_pid, ref) when is_pid(pid) and is_pid(target_pid) and is_reference(ref) do 139 - {:ok, %ProcState{} = proc_state} = fetch_state(table, pid) 140 - {:ok, %ProcState{} = target_state} = fetch_state(table, target_pid) 145 + def add_monitor(%ProcStore{} = ps, pid, target_pid, ref) when is_pid(pid) and is_pid(target_pid) and is_reference(ref) do 146 + {:ok, %ProcState{} = proc_state} = fetch_state(ps, pid) 147 + {:ok, %ProcState{} = target_state} = fetch_state(ps, target_pid) 141 148 142 149 monitors = Map.put(proc_state.monitors, ref, target_pid) 143 150 monitored_by = [{ref, pid} | target_state.monitored_by] 144 151 145 - :ets.insert(table, {pid, %{proc_state | monitors: monitors}}) 146 - :ets.insert(table, {target_pid, %{target_state | monitored_by: monitored_by}}) 152 + :ets.insert(ps.proc_table, {pid, %{proc_state | monitors: monitors}}) 153 + :ets.insert(ps.proc_table, {target_pid, %{target_state | monitored_by: monitored_by}}) 147 154 :ok 148 155 end 149 156 150 157 @spec remove_monitor(t, pid, reference) :: :ok 151 - def remove_monitor(table, pid, ref) do 152 - {:ok, %ProcState{} = proc_state} = fetch_state(table, pid) 158 + def remove_monitor(%ProcStore{} = ps, pid, ref) do 159 + {:ok, %ProcState{} = proc_state} = fetch_state(ps, pid) 153 160 154 161 {target_pid, monitors} = Map.pop!(proc_state.monitors, ref) 155 162 156 - {:ok, %ProcState{} = target_state} = fetch_state(table, target_pid) 163 + {:ok, %ProcState{} = target_state} = fetch_state(ps, target_pid) 157 164 monitored_by = 158 165 target_state.monitored_by 159 166 |> Enum.filter(fn ··· 161 168 _ -> true 162 169 end) 163 170 164 - :ets.insert(table, {pid, %{proc_state | monitors: monitors}}) 165 - :ets.insert(table, {target_pid, %{target_state | monitored_by: monitored_by}}) 171 + :ets.insert(ps.proc_table, {pid, %{proc_state | monitors: monitors}}) 172 + :ets.insert(ps.proc_table, {target_pid, %{target_state | monitored_by: monitored_by}}) 166 173 :ok 167 174 end 168 175 169 176 @spec set_flag(t, pid, :trap_exit, boolean) :: {:ok, boolean} 170 - def set_flag(table, pid, :trap_exit, value) when is_boolean(value) do 171 - {:ok, %ProcState{} = state} = fetch_state(table, pid) 177 + def set_flag(%ProcStore{} = ps, pid, :trap_exit, value) when is_boolean(value) do 178 + {:ok, %ProcState{} = state} = fetch_state(ps, pid) 172 179 173 - :ets.insert(table, {pid, %{state | trap_exit: value}}) 180 + :ets.insert(ps.proc_table, {pid, %{state | trap_exit: value}}) 174 181 {:ok, state.trap_exit} 175 182 end 176 183 end