prevent dead-lock during garbage-collection
This commit is contained in:
parent
771854002f
commit
83327c71dd
2 changed files with 49 additions and 58 deletions
|
@ -46,10 +46,6 @@ defmodule Floof.PacketSpool do
|
||||||
@impl true
|
@impl true
|
||||||
def init(state) do
|
def init(state) do
|
||||||
:ok = File.mkdir_p(state)
|
:ok = File.mkdir_p(state)
|
||||||
|
|
||||||
# in 5 seconds
|
|
||||||
Process.send_after(self(), :collect_garbage, 5 * 1000)
|
|
||||||
|
|
||||||
{:ok, state}
|
{:ok, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -134,22 +130,7 @@ defmodule Floof.PacketSpool do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_cast({:drop, hash}, state) do
|
def handle_call({:collect_garbage_keep_only, to_keep}, _, state) do
|
||||||
case File.rm(hash_to_path(hash, state)) do
|
|
||||||
:ok -> nil
|
|
||||||
{:error, e} -> Logger.error("spool: unable to remove #{inspect(hash)}: #{inspect(e)}")
|
|
||||||
end
|
|
||||||
|
|
||||||
{:noreply, state}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_info(:collect_garbage, state) do
|
|
||||||
case GenServer.call(Floof.SessionManager, :get_keep_only, :infinity) do
|
|
||||||
:error ->
|
|
||||||
nil
|
|
||||||
|
|
||||||
{:ok, to_keep} ->
|
|
||||||
{:ok, items} = File.ls(state)
|
{:ok, items} = File.ls(state)
|
||||||
|
|
||||||
present =
|
present =
|
||||||
|
@ -182,10 +163,16 @@ defmodule Floof.PacketSpool do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
{:noreply, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
# do this again in 15 seconds
|
@impl true
|
||||||
Process.send_after(self(), :collect_garbage, 15 * 1000)
|
def handle_cast({:drop, hash}, state) do
|
||||||
|
case File.rm(hash_to_path(hash, state)) do
|
||||||
|
:ok -> nil
|
||||||
|
{:error, e} -> Logger.error("spool: unable to remove #{inspect(hash)}: #{inspect(e)}")
|
||||||
|
end
|
||||||
|
|
||||||
{:noreply, state}
|
{:noreply, state}
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,7 @@ defmodule Floof.SessionManager do
|
||||||
@impl true
|
@impl true
|
||||||
def init({file, opts}) do
|
def init({file, opts}) do
|
||||||
{:ok, file} = :dets.open_file(file, opts ++ [type: :bag])
|
{:ok, file} = :dets.open_file(file, opts ++ [type: :bag])
|
||||||
|
Process.send_after(self(), :collect_garbage, 5 * 1000)
|
||||||
{:ok, %Floof.SessionManager{dets_file: file}}
|
{:ok, %Floof.SessionManager{dets_file: file}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -143,16 +144,19 @@ defmodule Floof.SessionManager do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call(:get_keep_only, _, state) do
|
def handle_info(:collect_garbage, state) do
|
||||||
{:reply,
|
|
||||||
case :dets.match(state.dets_file, {'_', '$2'}) do
|
case :dets.match(state.dets_file, {'_', '$2'}) do
|
||||||
{:error, e} ->
|
{:error, e} ->
|
||||||
Logger.error("garbage collection error: #{inspect(e)}")
|
Logger.error("garbage collection error: #{inspect(e)}")
|
||||||
:error
|
Process.send_after(self(), :collect_garbage, 60 * 1000)
|
||||||
|
|
||||||
keys ->
|
keys ->
|
||||||
{:ok, Enum.map(keys, fn [x] -> x end)}
|
to_keep = Enum.map(keys, fn [x] -> x end)
|
||||||
end, state}
|
GenServer.call(Floof.PacketSpool, {:collect_garbage_keep_only, to_keep}, :infinity)
|
||||||
|
Process.send_after(self(), :collect_garbage, 15 * 1000)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:noreply, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp all_session_keys(state) do
|
defp all_session_keys(state) do
|
||||||
|
|
Loading…
Reference in a new issue