live reload yaml in dev
This commit is contained in:
parent
6e86f54aa0
commit
9cd3d57433
2 changed files with 87 additions and 0 deletions
|
|
@ -34,6 +34,7 @@ defmodule Towerops.Application do
|
|||
SnmpKit.SnmpMgr.Config,
|
||||
SnmpKit.SnmpMgr.MIB
|
||||
] ++
|
||||
dev_only_workers() ++
|
||||
background_workers() ++
|
||||
[
|
||||
# Start to serve requests, typically the last entry
|
||||
|
|
@ -68,6 +69,18 @@ defmodule Towerops.Application do
|
|||
end
|
||||
end
|
||||
|
||||
# Configure dev-only workers - profile watcher for auto-reload
|
||||
defp dev_only_workers do
|
||||
if Application.get_env(:towerops, :env) == :dev do
|
||||
[
|
||||
# Watch YAML profiles for changes and auto-reload
|
||||
Towerops.Profiles.ProfileWatcher
|
||||
]
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
# Returns PubSub spec - uses Redis in production/clustered environments,
|
||||
# falls back to default PG2 adapter for Mix tasks and development
|
||||
defp pubsub_spec do
|
||||
|
|
|
|||
74
lib/towerops/profiles/profile_watcher.ex
Normal file
74
lib/towerops/profiles/profile_watcher.ex
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
defmodule Towerops.Profiles.ProfileWatcher do
|
||||
@moduledoc """
|
||||
Watches YAML profile files for changes and automatically reloads them.
|
||||
|
||||
Uses FileSystem to monitor the priv/profiles directory for file changes.
|
||||
When a .yaml or .yml file is created, modified, or deleted, triggers
|
||||
a reload of all profiles via YamlProfiles.reload/0.
|
||||
"""
|
||||
use GenServer
|
||||
|
||||
alias Towerops.Profiles.YamlProfiles
|
||||
|
||||
require Logger
|
||||
|
||||
@profiles_dir "priv/profiles"
|
||||
|
||||
def start_link(opts \\ []) do
|
||||
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(_opts) do
|
||||
# Get the absolute path to the profiles directory
|
||||
profiles_path = Path.join(Application.app_dir(:towerops), @profiles_dir)
|
||||
|
||||
# Start watching the profiles directory for changes
|
||||
{:ok, watcher_pid} = FileSystem.start_link(dirs: [profiles_path])
|
||||
FileSystem.subscribe(watcher_pid)
|
||||
|
||||
Logger.info("ProfileWatcher: Started watching #{profiles_path}")
|
||||
|
||||
{:ok, %{watcher_pid: watcher_pid, profiles_path: profiles_path}}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info({:file_event, _watcher_pid, {path, events}}, state) do
|
||||
# Only reload if it's a YAML file change
|
||||
if yaml_file?(path) and should_reload?(events) do
|
||||
Logger.info("ProfileWatcher: Detected change in #{Path.relative_to_cwd(path)}, reloading profiles...")
|
||||
|
||||
case YamlProfiles.reload() do
|
||||
{:ok, count} ->
|
||||
Logger.info("ProfileWatcher: Successfully reloaded #{count} profiles")
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("ProfileWatcher: Failed to reload profiles: #{inspect(reason)}")
|
||||
end
|
||||
end
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info({:file_event, _watcher_pid, :stop}, state) do
|
||||
Logger.warning("ProfileWatcher: File watcher stopped")
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
# Check if the file is a YAML profile file
|
||||
defp yaml_file?(path) do
|
||||
String.ends_with?(path, [".yaml", ".yml"])
|
||||
end
|
||||
|
||||
# Check if the events indicate we should reload
|
||||
# Reload on created, modified, or removed events
|
||||
# Don't reload on :undefined or other metadata-only changes
|
||||
defp should_reload?(events) when is_list(events) do
|
||||
Enum.any?(events, fn event ->
|
||||
event in [:created, :modified, :removed, :renamed]
|
||||
end)
|
||||
end
|
||||
|
||||
defp should_reload?(_), do: false
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue