Raxol.Core.Runtime.Plugins.PluginLifecycle (Raxol Core v2.4.0)

Copy Markdown View Source

GenServer for plugin lifecycle coordination.

Handles stateful plugin operations that require coordination:

  • Loading and unloading plugins
  • Enabling and disabling plugins
  • Managing plugin runtime state
  • File watching for hot reload
  • Timer-based operations

Design

This module is the "coordination layer" - it's a GenServer because it needs to:

  • Coordinate concurrent plugin operations
  • Manage timers for debounced reloads
  • Track per-plugin runtime state

Read-only operations should use PluginRegistry directly for better performance.

Usage

# Start lifecycle manager
{:ok, _pid} = PluginLifecycle.start_link([])

# Load a plugin
PluginLifecycle.load(:my_plugin, MyPlugin, %{config: "value"})

# Enable/disable
PluginLifecycle.enable(:my_plugin)
PluginLifecycle.disable(:my_plugin)

# Get runtime state
PluginLifecycle.get_state(:my_plugin)

Summary

Functions

Returns a specification to start this module under a supervisor.

Disables a plugin without unloading it.

Disables file watching.

Enables a loaded plugin.

Enables file watching for plugin hot reload.

Gets the configuration of a plugin.

Gets the runtime state of a plugin.

Gets the status of a plugin.

Lists all plugins with their status.

Loads a plugin module with optional configuration.

Reloads a plugin (unload + load).

Schedules a debounced reload for a plugin.

Updates the runtime state of a plugin.

Unloads a plugin, cleaning up state and unregistering.

Updates plugin configuration.

Types

plugin_id()

@type plugin_id() :: atom() | String.t()

plugin_state()

@type plugin_state() :: term()

plugin_status()

@type plugin_status() :: :loaded | :enabled | :disabled | :error

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

disable(plugin_id)

@spec disable(plugin_id()) :: :ok | {:error, term()}

Disables a plugin without unloading it.

disable_file_watching()

@spec disable_file_watching() :: :ok

Disables file watching.

enable(plugin_id)

@spec enable(plugin_id()) :: :ok | {:error, term()}

Enables a loaded plugin.

enable_file_watching(dirs)

@spec enable_file_watching([String.t()]) :: :ok

Enables file watching for plugin hot reload.

get_config(plugin_id)

@spec get_config(plugin_id()) :: map()

Gets the configuration of a plugin.

get_state(plugin_id)

@spec get_state(plugin_id()) :: {:ok, plugin_state()} | {:error, :not_found}

Gets the runtime state of a plugin.

get_status(plugin_id)

@spec get_status(plugin_id()) :: plugin_status() | nil

Gets the status of a plugin.

list_with_status()

@spec list_with_status() :: [{plugin_id(), plugin_status()}]

Lists all plugins with their status.

load(plugin_id, module, config \\ %{})

@spec load(plugin_id(), module(), map()) :: :ok | {:error, term()}

Loads a plugin module with optional configuration.

Registers in PluginRegistry and initializes lifecycle state.

reload(plugin_id)

@spec reload(plugin_id()) :: :ok | {:error, term()}

Reloads a plugin (unload + load).

schedule_reload(plugin_id, delay_ms \\ 500)

@spec schedule_reload(plugin_id(), non_neg_integer()) :: :ok

Schedules a debounced reload for a plugin.

Useful for file-watching scenarios where multiple changes should trigger only one reload.

set_state(plugin_id, state)

@spec set_state(plugin_id(), plugin_state()) :: :ok | {:error, :not_found}

Updates the runtime state of a plugin.

start_link(opts \\ [])

unload(plugin_id)

@spec unload(plugin_id()) :: :ok | {:error, term()}

Unloads a plugin, cleaning up state and unregistering.

update_config(plugin_id, config)

@spec update_config(plugin_id(), map()) :: :ok

Updates plugin configuration.