@@ -181,8 +181,22 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
181181 fmt .Println (srv .GetOpenAPI ())
182182 return nil
183183 }
184- handleSignals (ctx , logger , srv , process , pidFile )
184+
185+ // Create a context for graceful shutdown
186+ gracefulCtx , gracefulCancel := context .WithCancel (ctx )
187+ defer gracefulCancel ()
188+
189+ // Setup signal handlers (they will call gracefulCancel)
190+ handleSignals (gracefulCtx , gracefulCancel , logger , srv )
191+
192+ // Setup PID file cleanup
193+ if pidFile != "" {
194+ defer cleanupPIDFile (pidFile , logger )
195+ }
196+
185197 logger .Info ("Starting server on port" , "port" , port )
198+
199+ // Monitor process exit
186200 processExitCh := make (chan error , 1 )
187201 go func () {
188202 defer close (processExitCh )
@@ -193,18 +207,52 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
193207 processExitCh <- xerrors .Errorf ("failed to wait for process: %w" , err )
194208 }
195209 }
196- shutdownCtx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
197- defer cancel ()
198- if err := srv .Stop (shutdownCtx ); err != nil {
199- logger .Error ("Failed to stop server after process exit" , "error" , err )
210+
211+ select {
212+ case <- gracefulCtx .Done ():
213+ default :
214+ gracefulCancel ()
215+ }
216+ }()
217+
218+ // Start the server
219+ serverErrCh := make (chan error , 1 )
220+ go func () {
221+ defer close (serverErrCh )
222+ if err := srv .Start (); err != nil && ! errors .Is (err , context .Canceled ) && ! errors .Is (err , http .ErrServerClosed ) {
223+ serverErrCh <- err
200224 }
201225 }()
202- if err := srv .Start (); err != nil && ! errors .Is (err , context .Canceled ) && ! errors .Is (err , http .ErrServerClosed ) {
203- return xerrors .Errorf ("failed to start server: %w" , err )
226+
227+ select {
228+ case err := <- serverErrCh :
229+ if err != nil {
230+ return xerrors .Errorf ("failed to start server: %w" , err )
231+ }
232+ case <- gracefulCtx .Done ():
204233 }
234+
235+ if err := srv .SaveState ("shutdown" ); err != nil {
236+ logger .Error ("Failed to save state during shutdown" , "error" , err )
237+ }
238+
239+ // Stop the HTTP server
240+ shutdownCtx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
241+ defer cancel ()
242+ if err := srv .Stop (shutdownCtx ); err != nil {
243+ logger .Error ("Failed to stop HTTP server" , "error" , err )
244+ }
245+
246+ // Close the process
247+ if err := process .Close (logger , 5 * time .Second ); err != nil {
248+ logger .Error ("Failed to close process cleanly" , "error" , err )
249+ }
250+
205251 select {
206252 case err := <- processExitCh :
207- return xerrors .Errorf ("agent exited with error: %w" , err )
253+ if err != nil {
254+ return xerrors .Errorf ("agent exited with error: %w" , err )
255+ }
208256 default :
209257 }
210258 return nil
0 commit comments