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
2329func 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