Skip to content

Commit

Permalink
Clean up parent code_sync artifacts on pool shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismccord committed Dec 6, 2024
1 parent 439752e commit e64ad84
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 4 deletions.
8 changes: 8 additions & 0 deletions lib/flame/pool.ex
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ defmodule FLAME.Pool do
:name,
:runner_sup,
:task_sup,
:cleaner,
:terminator_sup,
:child_placement_sup,
:idle_shutdown_after,
Expand All @@ -222,6 +223,9 @@ defmodule FLAME.Pool do
])

Keyword.validate!(opts[:code_sync] || [], [
:get_path,
:extract_dir,
:tmp_dir,
:copy_apps,
:copy_paths,
:sync_beams,
Expand Down Expand Up @@ -395,6 +399,7 @@ defmodule FLAME.Pool do
)

terminator_sup = Keyword.fetch!(opts, :terminator_sup)
cleaner = Keyword.fetch!(opts, :cleaner)
child_placement_sup = Keyword.fetch!(opts, :child_placement_sup)
runner_opts = runner_opts(opts, terminator_sup)
min = Keyword.fetch!(opts, :min)
Expand All @@ -415,6 +420,9 @@ defmodule FLAME.Pool do
|> CodeSync.compute_changed_paths()

%CodeSync.PackagedStream{} = parent_stream = CodeSync.package_to_stream(code_sync)

:ok = FLAME.Pool.Cleaner.watch_path(cleaner, parent_stream.stream.path)

parent_stream
end

Expand Down
35 changes: 35 additions & 0 deletions lib/flame/pool/cleaner.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
defmodule FLAME.Pool.Cleaner do
@moduledoc false
use GenServer

def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: Keyword.fetch!(opts, :name))
end

def watch_path(server, path) do
GenServer.call(server, {:watch, path})
end

def list_paths(server) do
GenServer.call(server, :list)
end

def init(_opts) do
Process.flag(:trap_exit, true)
{:ok, %{paths: []}}
end

def handle_call({:watch, path}, _from, state) do
{:reply, :ok, %{state | paths: [path | state.paths]}}
end

def handle_call(:list, _from, state) do
{:reply, state.paths, state}
end

def terminate(_reason, state) do
for path <- state.paths, do: File.rm!(path)

:ok
end
end
3 changes: 3 additions & 0 deletions lib/flame/pool/supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ defmodule FLAME.Pool.Supervisor do
def init(opts) do
name = Keyword.fetch!(opts, :name)
runner_sup = Module.concat(name, "RunnerSup")
cleaner = Module.concat(name, "Cleaner")
terminator_sup = Module.concat(name, "TerminatorSup")
task_sup = Module.concat(name, "TaskSup")

Expand All @@ -22,13 +23,15 @@ defmodule FLAME.Pool.Supervisor do
pool_opts =
Keyword.merge(opts,
task_sup: task_sup,
cleaner: cleaner,
runner_sup: runner_sup,
terminator_sup: terminator_sup,
child_placement_sup: child_placement_sup
)

children =
[
{FLAME.Pool.Cleaner, name: cleaner},
{Task.Supervisor, name: task_sup, strategy: :one_for_one},
{DynamicSupervisor, name: runner_sup, strategy: :one_for_one},
{DynamicSupervisor, name: terminator_sup, strategy: :one_for_one},
Expand Down
30 changes: 26 additions & 4 deletions test/flame_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ defmodule FLAME.FLAMETest do
end

setup config do
runner_opts = Map.fetch!(config, :runner)
runner_sup = Module.concat(config.test, "RunnerSup")
pool_pid = start_supervised!({Pool, Keyword.merge(runner_opts, name: config.test)})
case config do
%{runner: runner_opts} ->
runner_sup = Module.concat(config.test, "RunnerSup")
pool_pid = start_supervised!({Pool, Keyword.merge(runner_opts, name: config.test)})

{:ok, runner_sup: runner_sup, pool_pid: pool_pid}
{:ok, runner_sup: runner_sup, pool_pid: pool_pid}

%{} ->
:ok
end
end

@tag runner: [min: 1, max: 2, max_concurrency: 2]
Expand Down Expand Up @@ -619,4 +624,21 @@ defmodule FLAME.FLAMETest do
assert_receive {:DOWN, _, _, ^runner, {:shutdown, :idle}}, 1000
end
end

test "code_sync artifact cleaner", config do
mock = FLAME.Test.CodeSyncMock.new()

cleaner = Module.concat(config.test, "Cleaner")

pool_pid =
start_supervised!(
{Pool, min: 1, max: 1, max_concurrency: 1, name: config.test, code_sync: mock.opts}
)

assert [artifact] = FLAME.Pool.Cleaner.list_paths(cleaner)
assert File.exists?(artifact)
assert FLAME.call(config.test, fn -> :works end) == :works
Supervisor.stop(pool_pid)
refute File.exists?(artifact)
end
end

0 comments on commit e64ad84

Please sign in to comment.