prevent dead-lock during garbage-collection

This commit is contained in:
Alain Zscheile 2022-11-27 23:12:03 +01:00
parent 771854002f
commit 83327c71dd
2 changed files with 49 additions and 58 deletions

View file

@ -46,10 +46,6 @@ defmodule Floof.PacketSpool do
@impl true
def init(state) do
:ok = File.mkdir_p(state)
# in 5 seconds
Process.send_after(self(), :collect_garbage, 5 * 1000)
{:ok, state}
end
@ -134,22 +130,7 @@ defmodule Floof.PacketSpool do
end
@impl true
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}
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} ->
def handle_call({:collect_garbage_keep_only, to_keep}, _, state) do
{:ok, items} = File.ls(state)
present =
@ -182,10 +163,16 @@ defmodule Floof.PacketSpool do
end
end
end
{:noreply, state}
end
# do this again in 15 seconds
Process.send_after(self(), :collect_garbage, 15 * 1000)
@impl true
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}
end

View file

@ -15,6 +15,7 @@ defmodule Floof.SessionManager do
@impl true
def init({file, opts}) do
{:ok, file} = :dets.open_file(file, opts ++ [type: :bag])
Process.send_after(self(), :collect_garbage, 5 * 1000)
{:ok, %Floof.SessionManager{dets_file: file}}
end
@ -143,16 +144,19 @@ defmodule Floof.SessionManager do
end
@impl true
def handle_call(:get_keep_only, _, state) do
{:reply,
def handle_info(:collect_garbage, state) do
case :dets.match(state.dets_file, {'_', '$2'}) do
{:error, e} ->
Logger.error("garbage collection error: #{inspect(e)}")
:error
Process.send_after(self(), :collect_garbage, 60 * 1000)
keys ->
{:ok, Enum.map(keys, fn [x] -> x end)}
end, state}
to_keep = Enum.map(keys, fn [x] -> x end)
GenServer.call(Floof.PacketSpool, {:collect_garbage_keep_only, to_keep}, :infinity)
Process.send_after(self(), :collect_garbage, 15 * 1000)
end
{:noreply, state}
end
defp all_session_keys(state) do