ExAthena.Web.Settings (ExAthena v0.20.0)

Copy Markdown View Source

User-editable tuning settings, backed by the web UI's gear modal.

ExAthena.Tuning made the rails configurable; they still lived in config.exs, so changing one meant editing source and restarting. This module puts the same keys behind a form: values are validated, written to ~/.ex_athena/web/settings.json, and applied to the application environment immediately — the next run picks them up without a restart. load/0 re-applies them at boot.

The schema below is the single source of truth. It drives the modal's rendering, the validation, and the set of keys allowed to reach the application environment — a form posts whatever the page contained, and app env is global process state, so an unknown key is dropped rather than written.

Defaults here intentionally repeat the module attributes they mirror. That duplication is deliberate: the attribute is the behavioural default used when nothing is configured at all (including for hosts that never open the web UI), and this is the value the form shows. A test asserts the schema covers every field so the two cannot silently diverge in coverage; a mismatch in value only changes what the form pre-fills.

Summary

Functions

Apply the persisted settings file to the application environment.

Every namespace the schema writes to.

Whether {ns, key} currently differs from its built-in default.

Where settings are stored. Override with config :ex_athena, :settings_path.

Drop every saved override and return all fields to their defaults.

Validate params (a flat "namespace.key" => string map from the form), apply what is valid, and persist.

Field groups, in display order.

Current effective value for each field, keyed {namespace, key}.

Functions

load()

@spec load() :: :ok

Apply the persisted settings file to the application environment.

namespaces()

@spec namespaces() :: [atom()]

Every namespace the schema writes to.

overridden?(id)

@spec overridden?({atom(), atom()}) :: boolean()

Whether {ns, key} currently differs from its built-in default.

path()

@spec path() :: String.t()

Where settings are stored. Override with config :ex_athena, :settings_path.

reset()

@spec reset() :: :ok

Drop every saved override and return all fields to their defaults.

save(params)

@spec save(map()) :: {:ok, map()} | {:error, map()}

Validate params (a flat "namespace.key" => string map from the form), apply what is valid, and persist.

Returns {:ok, applied} or {:error, errors} keyed by {ns, key}. Valid fields are applied even when a sibling fails — a typo in one box should not discard the other edits the user just made.

schema()

@spec schema() :: [map()]

Field groups, in display order.

values()

@spec values() :: %{required({atom(), atom()}) => term()}

Current effective value for each field, keyed {namespace, key}.

Reads through ExAthena.Tuning, so a value set in config.exs shows in the form even though it was never saved here.