Skip to content

Commit 5c13f4e

Browse files
committed
refactor: delegate supervisor logic to Caddy.Supervisor module
Move the supervisor implementation from Caddy module to a dedicated Caddy.Supervisor module for better separation of concerns. The Caddy module now acts as a clean facade that delegates to Caddy.Supervisor, while maintaining full backward compatibility with existing code. Changes: - Create new Caddy.Supervisor module containing supervisor implementation - Update Caddy module to delegate start_link, restart_server, and stop - Update Caddy.ConfigProvider and Caddy.Admin to call Caddy.Supervisor.restart_server - Caddy.Application continues to use {Caddy, args} as entry point All existing APIs remain unchanged and fully backward compatible.
1 parent 889073b commit 5c13f4e

File tree

4 files changed

+87
-40
lines changed

4 files changed

+87
-40
lines changed

lib/caddy.ex

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,18 @@ defmodule Caddy do
4949
```
5050
5151
"""
52-
require Logger
5352

54-
use Supervisor
53+
@doc """
54+
Start the Caddy supervisor as part of a supervision tree.
55+
"""
56+
@spec start_link(Keyword.t()) :: :ignore | {:error, any()} | {:ok, pid()}
57+
defdelegate start_link(args), to: Caddy.Supervisor
5558

5659
@doc """
5760
Restart Caddy Server
5861
"""
5962
@spec restart_server :: {:ok, pid()} | {:ok, :undefined} | {:error, term()}
60-
def restart_server do
61-
case Supervisor.restart_child(__MODULE__, Caddy.Server) do
62-
{:error, :running} ->
63-
Supervisor.terminate_child(__MODULE__, Caddy.Server)
64-
Supervisor.restart_child(__MODULE__, Caddy.Server)
65-
66-
out ->
67-
out
68-
end
69-
end
63+
defdelegate restart_server, to: Caddy.Supervisor
7064

7165
@doc """
7266
Manually Start Caddy Server.
@@ -83,34 +77,13 @@ defmodule Caddy do
8377
start_link(caddy_bin: caddy_bin)
8478
end
8579

80+
@doc """
81+
Stop Caddy Server
82+
"""
8683
@spec stop(term()) :: :ok
87-
def stop(reason \\ :normal) do
88-
Supervisor.stop(__MODULE__, reason)
89-
end
90-
91-
@spec start_link(Keyword.t()) :: :ignore | {:error, any()} | {:ok, pid()}
92-
def start_link(args) do
93-
Supervisor.start_link(__MODULE__, args, name: __MODULE__)
94-
end
95-
96-
@impl true
97-
@spec init(any()) ::
98-
{:ok,
99-
{Supervisor.sup_flags(),
100-
[Supervisor.child_spec() | (old_erlang_child_spec :: :supervisor.child_spec())]}}
101-
def init(args) do
102-
children = [
103-
{Caddy.ConfigProvider, [args]},
104-
Caddy.Logger,
105-
Caddy.Server
106-
# Caddy.Admin
107-
]
108-
109-
opts = [strategy: :rest_for_one, name: __MODULE__]
110-
111-
Supervisor.init(children, opts)
112-
end
84+
defdelegate stop(reason \\ :normal), to: Caddy.Supervisor
11385

86+
# Configuration management functions delegated to ConfigProvider
11487
defdelegate set_bin(bin_path), to: Caddy.ConfigProvider
11588
defdelegate set_bin!(bin_path), to: Caddy.ConfigProvider
11689
defdelegate set_global(global), to: Caddy.ConfigProvider

lib/caddy/admin.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ defmodule Caddy.Admin do
3232
rescue
3333
error ->
3434
Logger.error("Caddy Admin: check_caddy_server failed #{inspect(error)}")
35-
Caddy.restart_server()
35+
Caddy.Supervisor.restart_server()
3636
end
3737
end

lib/caddy/config_provider.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ defmodule Caddy.ConfigProvider do
7575
@spec set_bin!(binary()) :: :ok | {:error, term()}
7676
def set_bin!(caddy_bin) do
7777
Agent.update(__MODULE__, &Map.put(&1, :bin, caddy_bin))
78-
Caddy.restart_server()
78+
Caddy.Supervisor.restart_server()
7979
end
8080

8181
@doc "Set global configuration"

lib/caddy/supervisor.ex

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
defmodule Caddy.Supervisor do
2+
@moduledoc """
3+
Main supervisor for the Caddy subsystem.
4+
5+
Manages the Caddy configuration, logging, and server processes
6+
using a rest_for_one strategy to ensure proper restart ordering.
7+
8+
## Supervision Tree
9+
10+
- `Caddy.ConfigProvider` - Agent for configuration management
11+
- `Caddy.Logger` - Logging subsystem with buffer and storage
12+
- `Caddy.Server` - GenServer managing the Caddy binary process
13+
14+
The rest_for_one strategy ensures that if the ConfigProvider crashes,
15+
all subsequent children are restarted. If the Logger crashes, only
16+
the Server is restarted.
17+
"""
18+
19+
use Supervisor
20+
21+
@doc """
22+
Start the Caddy supervisor.
23+
24+
## Options
25+
26+
- `:caddy_bin` - Path to the Caddy binary (optional)
27+
"""
28+
@spec start_link(Keyword.t()) :: :ignore | {:error, any()} | {:ok, pid()}
29+
def start_link(args) do
30+
Supervisor.start_link(__MODULE__, args, name: __MODULE__)
31+
end
32+
33+
@impl true
34+
@spec init(any()) ::
35+
{:ok,
36+
{Supervisor.sup_flags(),
37+
[Supervisor.child_spec() | (old_erlang_child_spec :: :supervisor.child_spec())]}}
38+
def init(args) do
39+
children = [
40+
{Caddy.ConfigProvider, [args]},
41+
Caddy.Logger,
42+
Caddy.Server
43+
]
44+
45+
opts = [strategy: :rest_for_one, name: __MODULE__]
46+
47+
Supervisor.init(children, opts)
48+
end
49+
50+
@doc """
51+
Restart the Caddy Server child process.
52+
53+
Returns `{:ok, pid()}` on successful restart, or `{:error, term()}` on failure.
54+
"""
55+
@spec restart_server :: {:ok, pid()} | {:ok, :undefined} | {:error, term()}
56+
def restart_server do
57+
case Supervisor.restart_child(__MODULE__, Caddy.Server) do
58+
{:error, :running} ->
59+
Supervisor.terminate_child(__MODULE__, Caddy.Server)
60+
Supervisor.restart_child(__MODULE__, Caddy.Server)
61+
62+
out ->
63+
out
64+
end
65+
end
66+
67+
@doc """
68+
Stop the Caddy supervisor.
69+
"""
70+
@spec stop(term()) :: :ok
71+
def stop(reason \\ :normal) do
72+
Supervisor.stop(__MODULE__, reason)
73+
end
74+
end

0 commit comments

Comments
 (0)