diff --git a/lib/flame/code_sync.ex b/lib/flame/code_sync.ex index a360798..605c079 100644 --- a/lib/flame/code_sync.ex +++ b/lib/flame/code_sync.ex @@ -216,7 +216,7 @@ defmodule FLAME.CodeSync do defp trim_leading_slash([?/ | path]), do: path defp trim_leading_slash([_ | _] = path), do: path - def extract_packaged_stream(%PackagedStream{} = pkg) do + def extract_packaged_stream(%PackagedStream{} = pkg, terminator) do if pkg.stream do verbose = if pkg.verbose, do: [:verbose], else: [] compressed = if pkg.compress, do: [:compressed], else: [] @@ -232,6 +232,9 @@ defmodule FLAME.CodeSync do # add code paths :ok = add_code_paths_from_tar(pkg, extract_dir) + # add path to clean up + FLAME.Terminator.watch_path(terminator, extract_dir) + File.rm(target_tmp_path) # purge any deleted modules diff --git a/lib/flame/runner.ex b/lib/flame/runner.ex index 5dd2649..6e70a34 100644 --- a/lib/flame/runner.ex +++ b/lib/flame/runner.ex @@ -253,8 +253,10 @@ defmodule FLAME.Runner do new_state {new_state, %CodeSync.PackagedStream{} = parent_pkg} -> + terminator = state.runner.terminator + remote_call!(state.runner, state.backend_state, state.runner.boot_timeout, false, fn -> - :ok = CodeSync.extract_packaged_stream(parent_pkg) + :ok = CodeSync.extract_packaged_stream(parent_pkg, terminator) end) CodeSync.rm_packaged_stream(parent_pkg) @@ -306,8 +308,13 @@ defmodule FLAME.Runner do # ensure app is fully started if parent connects before up if otp_app, do: {:ok, _} = Application.ensure_all_started(otp_app) - if base_sync_stream, do: CodeSync.extract_packaged_stream(base_sync_stream) - if beams_stream, do: CodeSync.extract_packaged_stream(beams_stream) + if base_sync_stream do + CodeSync.extract_packaged_stream(base_sync_stream, term) + end + + if beams_stream do + CodeSync.extract_packaged_stream(beams_stream, term) + end :ok = Terminator.schedule_idle_shutdown(term, idle_after, idle_check, single_use) diff --git a/lib/flame/terminator.ex b/lib/flame/terminator.ex index c0fbc29..3871123 100644 --- a/lib/flame/terminator.ex +++ b/lib/flame/terminator.ex @@ -32,6 +32,7 @@ defmodule FLAME.Terminator do single_use: false, calls: %{}, watchers: %{}, + paths: [], log: false, status: nil, failsafe_timer: nil, @@ -73,6 +74,10 @@ defmodule FLAME.Terminator do GenServer.call(terminator, {:watch, pids}) end + def watch_path(terminator, path) do + GenServer.call(terminator, {:watch_path, path}) + end + def deadline_me(terminator, timeout) do GenServer.call(terminator, {:deadline, timeout}) end @@ -263,6 +268,10 @@ defmodule FLAME.Terminator do {:reply, :ok, cancel_idle_shutdown(state)} end + def handle_call({:watch_path, path}, _from, %Terminator{watchers: paths} = state) do + {:reply, :ok, %{state | paths: [path | paths]}} + end + def handle_call(:system_shutdown, _from, %Terminator{} = state) do {:reply, :ok, system_stop(state, "system shutdown instructed from parent #{inspect(state.parent.pid)}")} @@ -288,6 +297,12 @@ defmodule FLAME.Terminator do {:reply, :ok, schedule_idle_shutdown(new_state)} end + defp clean_up_paths(paths) do + for path <- paths do + File.rm_rf(path) + end + end + @impl true def terminate(_reason, %Terminator{} = state) do state = @@ -295,6 +310,9 @@ defmodule FLAME.Terminator do |> cancel_idle_shutdown() |> system_stop("terminating") + # clean up any paths that were watched before waiting to not be killed + clean_up_paths(state.paths) + # supervisor will force kill us if we take longer than configured shutdown_timeout Enum.each(state.calls, fn # skip callers that placed a child since they are on the remote node