Lemon.Reload (lemon_core v0.1.0)

View Source

Runtime hot-reload helpers built on BEAM code loading primitives.

This module provides two distinct reload paths:

It also exposes reload_system/1 for orchestrated reload workflows under one global lock: app reloads, extension reloads, and code_change/3 callbacks for live OTP processes.

When callers pass compile: true, source-based runtimes first run mix compile inside the live node before reloading modules from disk. Releases still support BEAM reload, but explicit source compilation is unavailable there because Mix is not running.

Summary

Types

compile_metadata()

@type compile_metadata() :: %{
  ran: true,
  source: :mix | :custom,
  force: boolean(),
  duration_ms: non_neg_integer()
}

error_item()

@type error_item() :: %{target: module() | String.t() | atom(), reason: term()}

reload_kind()

@type reload_kind() :: :module | :app | :extension | :code_change | :system

result()

@type result() :: %{
  kind: reload_kind(),
  target: module() | atom() | String.t(),
  status: :ok | :partial | :error,
  reloaded: [module()],
  skipped: [skip_item()],
  errors: [error_item()],
  duration_ms: non_neg_integer(),
  metadata: map()
}

skip_item()

@type skip_item() :: %{target: module() | String.t() | atom(), reason: term()}

Functions

reload_app(app, opts \\ [])

@spec reload_app(
  atom(),
  keyword()
) :: {:ok, result()} | {:error, term()}

reload_extension(path, opts \\ [])

@spec reload_extension(
  String.t(),
  keyword()
) :: {:ok, result()} | {:error, term()}

reload_module(module, opts \\ [])

@spec reload_module(
  module(),
  keyword()
) :: {:ok, result()} | {:error, term()}

reload_system(opts \\ [])

@spec reload_system(keyword()) :: {:ok, result()} | {:error, term()}

Orchestrate a full runtime reload under one global lock.

Options

  • :apps - list of app atoms to reload via BEAM (:code.load_file/1)
  • :extensions - list of extension source paths to compile/reload
  • :code_change_targets - list of code-change targets; each target may be:
    • %{server: atom() | pid(), module: module(), old_vsn: term(), extra: term()}

    • {server, module}
    • {server, module, old_vsn}
    • {server, module, old_vsn, extra}
  • :lock_nodes - distributed lock nodes (default: [node()])
  • :lock_retries - :global.trans/4 retries (default: 0)

soft_purge_module(module, opts \\ [])

@spec soft_purge_module(
  module(),
  keyword()
) :: {:ok, result()} | {:error, term()}