LemonGateway.DependencyManager (lemon_gateway v0.1.0)

View Source

Centralized dependency availability and startup manager for LemonGateway.

Engines, tools, and transport modules previously contained scattered Application.ensure_all_started/1 and Code.ensure_loaded?/1 calls. This module provides a single boundary for:

  • Ensuring OTP applications are started before use (ensure_app/1)
  • Checking module availability without starting apps (available?/1)
  • Caching availability results to avoid repeated Code.ensure_loaded? calls

Usage

case DependencyManager.ensure_app(:coding_agent) do
  :ok -> # proceed
  {:error, reason} -> # handle failure
end

if DependencyManager.available?(LemonCore.Bus) do
  LemonCore.Bus.broadcast(topic, event)
end

Summary

Functions

Check whether a module is loaded and available for use.

Safely emit an event to LemonCore.Bus if available.

Safely emit telemetry if LemonCore.Telemetry is available.

Ensure an OTP application and its dependencies are started.

Check whether a module exports a specific function.

Functions

available?(mod)

@spec available?(module()) :: boolean()

Check whether a module is loaded and available for use.

Uses Code.ensure_loaded?/1 under the hood. Suitable for optional dependencies that may not be present in all deployment configurations (e.g., LemonCore.Bus, LemonCore.Telemetry, LemonCore.Event).

broadcast(topic, event)

@spec broadcast(String.t(), term()) :: :ok

Safely emit an event to LemonCore.Bus if available.

Returns :ok regardless of whether the bus is available.

build_event(event_type, payload, meta)

@spec build_event(atom(), map(), map()) :: LemonCore.Event.t()

Build a LemonCore.Event.

This used to fall back to a bare {event_type, payload} tuple when LemonCore.Event was not loadable, from when the gateway was meant to run without core. lemon_core is a hard dependency, so that branch was unreachable — but it was a second wire shape on the bus, and consumers grew receive clauses for a tuple no one could publish. One shape now.

emit_telemetry(function_name, args)

@spec emit_telemetry(atom(), list()) :: :ok

Safely emit telemetry if LemonCore.Telemetry is available.

Accepts the telemetry function name and its arguments. Returns :ok regardless of availability.

ensure_app(app)

@spec ensure_app(atom()) :: :ok | {:error, term()}

Ensure an OTP application and its dependencies are started.

Returns :ok on success, {:error, reason} on failure. This is the unified replacement for scattered Application.ensure_all_started/1 calls in engine, tool, and transport modules.

exports?(mod, fun, arity)

@spec exports?(module(), atom(), non_neg_integer()) :: boolean()

Check whether a module exports a specific function.

Combines Code.ensure_loaded?/1 with function_exported?/3.