-
Notifications
You must be signed in to change notification settings - Fork 713
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: flyteadmin doesn't shutdown servers gracefully #6289
base: master
Are you sure you want to change the base?
Changes from 6 commits
490e289
09cdb5f
a264c15
8a7722f
d1714f6
cdb0383
9d3b73b
6d76383
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,10 @@ | |
"fmt" | ||
"net" | ||
"net/http" | ||
"os" | ||
"os/signal" | ||
"strings" | ||
"syscall" | ||
"time" | ||
|
||
"github.com/gorilla/handlers" | ||
|
@@ -386,8 +389,9 @@ | |
} | ||
|
||
go func() { | ||
err := grpcServer.Serve(lis) | ||
logger.Fatalf(ctx, "Failed to create GRPC Server, Err: ", err) | ||
if err := grpcServer.Serve(lis); err != nil { | ||
logger.Fatalf(ctx, "Failed to create GRPC Server, Err: %v", err) | ||
} | ||
}() | ||
|
||
logger.Infof(ctx, "Starting HTTP/1 Gateway server on %s", cfg.GetHostAddress()) | ||
|
@@ -422,11 +426,34 @@ | |
ReadHeaderTimeout: time.Duration(cfg.ReadHeaderTimeoutSeconds) * time.Second, | ||
} | ||
|
||
err = server.ListenAndServe() | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to Start HTTP Server") | ||
go func() { | ||
err = server.ListenAndServe() | ||
if err != nil && err != http.ErrServerClosed { | ||
logger.Fatalf(ctx, "Failed to start HTTP Server: %v", err) | ||
} | ||
}() | ||
|
||
// Gracefully shutdown the servers | ||
sigCh := make(chan os.Signal, 1) | ||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) | ||
<-sigCh | ||
time.Sleep(1 * time.Second) | ||
lowc1012 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// force to shut down servers after 10 seconds | ||
timer := time.AfterFunc(10 * time.Second, func() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May want to make this timeout configurable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like configure the timeout in flyteadmin_config.yaml?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. Something along those lines. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||
logger.Infof(ctx, "Server couldn't stop gracefully in time. Doing force stop.") | ||
server.Close() | ||
grpcServer.Stop() | ||
}) | ||
defer timer.Stop() | ||
|
||
grpcServer.GracefulStop() | ||
|
||
if err := server.Shutdown(ctx); err != nil { | ||
logger.Errorf(ctx, "Failed to gracefully shutdown HTTP server: %v", err) | ||
} | ||
|
||
logger.Infof(ctx, "Servers gracefully stopped") | ||
return nil | ||
} | ||
|
||
|
@@ -534,10 +561,26 @@ | |
ReadHeaderTimeout: time.Duration(cfg.ReadHeaderTimeoutSeconds) * time.Second, | ||
} | ||
|
||
err = srv.Serve(tls.NewListener(conn, srv.TLSConfig)) | ||
go func() { | ||
err = srv.Serve(tls.NewListener(conn, srv.TLSConfig)) | ||
if err != nil && err != http.ErrServerClosed { | ||
logger.Errorf(ctx, "Failed to start HTTP/2 Server: %v", err) | ||
} | ||
}() | ||
Comment on lines
+565
to
+570
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential race condition in server startup
The HTTP/2 server is now started in a goroutine, but the function immediately proceeds to wait for shutdown signals. This could lead to a race condition where the shutdown sequence begins before the server is fully initialized. Consider adding a small delay or a readiness check before proceeding to the shutdown logic. Code suggestionCheck the AI-generated fix before applying
Code Review Run #55c786 Should Bito avoid suggestions like this for future reviews? (Manage Rules)
|
||
|
||
// Gracefully shutdown the servers | ||
sigCh := make(chan os.Signal, 1) | ||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) | ||
<-sigCh | ||
|
||
if err != nil { | ||
return errors.Wrapf(err, "failed to Start HTTP/2 Server") | ||
// Create a context with timeout for the shutdown process | ||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancel() | ||
|
||
if err := srv.Shutdown(shutdownCtx); err != nil { | ||
logger.Errorf(ctx, "Failed to shutdown HTTP server: %v", err) | ||
} | ||
|
||
logger.Infof(ctx, "Servers gracefully stopped") | ||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to have two signal listeners? Should just be able to use one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you mean just
SIGINT
orSIGTERM
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean that in this diff you have two signal channels (one for grpc and one for http). You only need one to know whether or not the app is shutting down.