Skip to content

Commit f78a187

Browse files
committed
feat: config hot-reload
1 parent 2bb66a5 commit f78a187

File tree

1 file changed

+28
-10
lines changed

1 file changed

+28
-10
lines changed

llama-swap.go

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os"
99
"os/signal"
1010
"path/filepath"
11+
"sync"
1112
"syscall"
1213
"time"
1314

@@ -16,9 +17,14 @@ import (
1617
"github.com/mostlygeek/llama-swap/proxy"
1718
)
1819

19-
var version string = "0"
20-
var commit string = "abcd1234"
21-
var date = "unknown"
20+
var (
21+
version string = "0"
22+
commit string = "abcd1234"
23+
date string = "unknown"
24+
25+
// Global mutex for server operations
26+
serverMux sync.Mutex
27+
)
2228

2329
func main() {
2430
// Define a command-line flag for the port
@@ -78,18 +84,31 @@ func main() {
7884
fmt.Println("llama-swap listening on " + *listenStr)
7985
go func() {
8086
for {
81-
err = proxyManager.Run(*listenStr)
87+
serverMux.Lock()
88+
runChan := make(chan error)
89+
90+
// Start server in separate goroutine
91+
go func() {
92+
runChan <- proxyManager.Run(*listenStr)
93+
}()
94+
95+
// Wait for server to complete or config reload
96+
err = <-runChan
97+
8298
if err != nil && err != http.ErrServerClosed {
8399
fmt.Printf("Fatal server error: %v\n", err)
100+
serverMux.Unlock()
84101
close(exitChan)
85102
return
86103
}
104+
105+
serverMux.Unlock()
87106
// If we get here, it's because of a normal shutdown (config reload)
88107
// Just continue the loop to let the new server start
89108
}
90109
}()
91110

92-
// Wait until we receive an exit signal
111+
// Wait for exit signal
93112
<-exitChan
94113
}
95114

@@ -117,7 +136,6 @@ func watchConfigFile(configPath string, pm **proxy.ProxyManager, listenStr *stri
117136
select {
118137
case event, ok := <-watcher.Events:
119138
if !ok {
120-
log.Println("File watcher channel closed.")
121139
return
122140
}
123141
// We only care about writes to the specific config file
@@ -137,18 +155,18 @@ func watchConfigFile(configPath string, pm **proxy.ProxyManager, listenStr *stri
137155
}
138156

139157
// Stop and cleanup old ProxyManager
158+
serverMux.Lock()
140159
oldPM := *pm
141160
oldPM.Shutdown()
142161

143162
// Create new ProxyManager with new config
144163
newPM := proxy.New(newConfig)
145164
*pm = newPM
165+
serverMux.Unlock()
146166

147-
// Wait for a moment to ensure shutdown is complete
148-
time.Sleep(250 * time.Millisecond)
149-
150-
// Start serving with new ProxyManager
167+
// Start serving with new ProxyManager (outside the lock)
151168
go func() {
169+
// Try to start the server
152170
if err := newPM.Run(*listenStr); err != nil && err != http.ErrServerClosed {
153171
log.Printf("Error starting server after config reload: %v", err)
154172
}

0 commit comments

Comments
 (0)