Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,14 @@ hooks:
preload:
- "llama"
```

## Hot Reloading Configuration

Trigger a configuration reload by sending `SIGHUP` to the process:

- **With Docker** (if container is named `llama-swap`):
```bash
docker kill -s SIGHUP llama-swap
```

For real-time file system monitoring and automatic restarts on config changes, see [restart-on-config-change](./examples/restart-on-config-change/README.md).
39 changes: 23 additions & 16 deletions docs/examples/restart-on-config-change/README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
# Restart llama-swap on config change

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.
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 `SIGHUP` signal to `llama-swap` to trigger a config file reload when it detects a change.

```bash
#!/bin/bash
#
# A simple watch and restart llama-swap when its configuration
# file changes. Useful for trying out configuration changes
# without manually restarting the server each time.

# For docker users, consider replacing:
# `kill -USR1 $PID` with `docker kill -s SIGHUP container_name`

if [ -z "$1" ]; then
echo "Usage: $0 <path to config.yaml>"
exit 1
fi

while true; do
# Start the process again
./llama-swap-linux-amd64 -config $1 -listen :1867 &
PID=$!
echo "Started llama-swap with PID $PID"
# Start the process once
./llama-swap-linux-amd64 -config $1 -listen :1867 &
PID=$!
echo "Started llama-swap with PID $PID"

while true; do
# Wait for modifications in the specified directory or file
inotifywait -e modify "$1"
if ! inotifywait -e modify "$1" 2>/dev/null; then
echo "Error: Failed to monitor file changes"
break
fi

# Check if process exists before sending signal
if kill -0 $PID 2>/dev/null; then
echo "Sending SIGTERM to $PID"
kill -SIGTERM $PID
wait $PID
echo "Sending SIGHUP to $PID"
kill -USR1 $PID
else
echo "Process $PID no longer exists"
break
fi
sleep 1
done
Expand All @@ -42,10 +49,10 @@ Started llama-swap with PID 495455
Setting up watches.
Watches established.
llama-swap listening on :1867
Sending SIGTERM to 495455
Shutting down llama-swap
Started llama-swap with PID 495486
Setting up watches.
Watches established.
llama-swap listening on :1867
...
Sending SIGHUP to 495455
Received SIGHUP. Reloading configuration...
Configuration Changed
Configuration Reloaded
...
```
41 changes: 26 additions & 15 deletions llama-swap.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func main() {
// Setup channels for server management
exitChan := make(chan struct{})
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

// Create server with initial handler
srv := &http.Server{
Expand Down Expand Up @@ -170,23 +170,34 @@ func main() {
}()
}

// shutdown on signal
// shutdown on SIGINT/SIGTERM
// reload config on SIGHUP
go func() {
sig := <-sigChan
fmt.Printf("Received signal %v, shutting down...\n", sig)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()

if pm, ok := srv.Handler.(*proxy.ProxyManager); ok {
pm.Shutdown()
} else {
fmt.Println("srv.Handler is not of type *proxy.ProxyManager")
}
for sig := range sigChan {
switch sig {
case syscall.SIGINT, syscall.SIGTERM:
fmt.Printf("Received signal %v, shutting down...\n", sig)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()

if pm, ok := srv.Handler.(*proxy.ProxyManager); ok {
pm.Shutdown()
} else {
fmt.Println("srv.Handler is not of type *proxy.ProxyManager")
}

if err := srv.Shutdown(ctx); err != nil {
fmt.Printf("Server shutdown error: %v\n", err)
if err := srv.Shutdown(ctx); err != nil {
fmt.Printf("Server shutdown error: %v\n", err)
}
close(exitChan)
return
case syscall.SIGHUP:
fmt.Println("Received SIGHUP. Reloading configuration...")
reloadProxyManager()
default:
log.Printf("Unhandled signal: %v", sig)
}
}
close(exitChan)
}()

// Start server
Expand Down
Loading