Skip to content

Commit f4ff658

Browse files
committed
feat: reload config on SIGUSR1
- Allows quick reloading with SIGUSR1 without when filesytem watch is not available like on a default docker setup `docker kill -s SIGUSR1` - Also refactored the signal handling in a single logical unit Signed-off-by: blob42 <[email protected]>
1 parent dea9873 commit f4ff658

File tree

3 files changed

+46
-25
lines changed

3 files changed

+46
-25
lines changed

docs/configuration.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,3 +384,14 @@ hooks:
384384
preload:
385385
- "llama"
386386
```
387+
388+
## Hot Reloading Configuration
389+
390+
Trigger a configuration reload by sending `SIGUSR1` to the process:
391+
392+
- **With Docker** (if container is named `llama-swap`):
393+
```bash
394+
docker kill -s SIGUSR1 llama-swap
395+
```
396+
397+
For real-time file system monitoring and automatic restarts on config changes, see [restart-on-config-change](./examples/restart-on-config-change/README.md).

docs/examples/restart-on-config-change/README.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Restart llama-swap on config change
22

3-
Sometimes editing the configuration file can take a bit of trail and error to get a model configuration tuned just right. The `watch-and-restart.sh` script can be used to watch `config.yaml` for changes and restart `llama-swap` when it detects a change.
3+
Sometimes editing the configuration file can take a bit of trial and error to get a model configuration tuned just right. The `watch-and-restart.sh` script can be used to watch `config.yaml` for changes and send the `SIGUSR1` signal to `llama-swap` to trigger a config file reload when it detects a change.
44

55
```bash
66
#!/bin/bash
@@ -24,9 +24,8 @@ while true; do
2424

2525
# Check if process exists before sending signal
2626
if kill -0 $PID 2>/dev/null; then
27-
echo "Sending SIGTERM to $PID"
28-
kill -SIGTERM $PID
29-
wait $PID
27+
echo "Sending SIGUSR1 to $PID"
28+
kill -USR1 $PID
3029
else
3130
echo "Process $PID no longer exists"
3231
fi
@@ -42,10 +41,10 @@ Started llama-swap with PID 495455
4241
Setting up watches.
4342
Watches established.
4443
llama-swap listening on :1867
45-
Sending SIGTERM to 495455
46-
Shutting down llama-swap
47-
Started llama-swap with PID 495486
48-
Setting up watches.
49-
Watches established.
50-
llama-swap listening on :1867
44+
...
45+
Sending SIGUSR1 to 495455
46+
Received SIGUSR1. Reloading configuration...
47+
Configuration Changed
48+
Configuration Reloaded
49+
...
5150
```

llama-swap.go

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func main() {
7777
// Setup channels for server management
7878
exitChan := make(chan struct{})
7979
sigChan := make(chan os.Signal, 1)
80-
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
80+
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1)
8181

8282
// Create server with initial handler
8383
srv := &http.Server{
@@ -170,23 +170,34 @@ func main() {
170170
}()
171171
}
172172

173-
// shutdown on signal
173+
// shutdown on SIGINT/SIGTERM
174+
// reload config on SIGUSR1
174175
go func() {
175-
sig := <-sigChan
176-
fmt.Printf("Received signal %v, shutting down...\n", sig)
177-
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
178-
defer cancel()
179-
180-
if pm, ok := srv.Handler.(*proxy.ProxyManager); ok {
181-
pm.Shutdown()
182-
} else {
183-
fmt.Println("srv.Handler is not of type *proxy.ProxyManager")
184-
}
176+
for sig := range sigChan {
177+
switch sig {
178+
case syscall.SIGINT, syscall.SIGTERM:
179+
fmt.Printf("Received signal %v, shutting down...\n", sig)
180+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
181+
defer cancel()
182+
183+
if pm, ok := srv.Handler.(*proxy.ProxyManager); ok {
184+
pm.Shutdown()
185+
} else {
186+
fmt.Println("srv.Handler is not of type *proxy.ProxyManager")
187+
}
185188

186-
if err := srv.Shutdown(ctx); err != nil {
187-
fmt.Printf("Server shutdown error: %v\n", err)
189+
if err := srv.Shutdown(ctx); err != nil {
190+
fmt.Printf("Server shutdown error: %v\n", err)
191+
}
192+
close(exitChan)
193+
return
194+
case syscall.SIGUSR1:
195+
fmt.Println("Received SIGUSR1. Reloading configuration...")
196+
reloadProxyManager()
197+
default:
198+
log.Printf("Unhandled signal: %v", sig)
199+
}
188200
}
189-
close(exitChan)
190201
}()
191202

192203
// Start server

0 commit comments

Comments
 (0)