diff --git a/.DS_Store b/.DS_Store index ec65982af..9f2958c3b 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/App.go b/App.go index 25ce12381..8a1f6589d 100644 --- a/App.go +++ b/App.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "github.com/devtron-labs/common-lib/constants" "github.com/devtron-labs/common-lib/middlewares" @@ -8,6 +9,7 @@ import ( client "github.com/devtron-labs/kubelink/grpc" "github.com/devtron-labs/kubelink/pkg/k8sInformer" "github.com/devtron-labs/kubelink/pkg/service" + "github.com/go-pg/pg" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "go.uber.org/zap" @@ -27,15 +29,19 @@ type App struct { ServerImpl *service.ApplicationServiceServerImpl router *router.RouterImpl k8sInformer k8sInformer.K8sInformer + db *pg.DB + server *http.Server + grpcServer *grpc.Server } func NewApp(Logger *zap.SugaredLogger, ServerImpl *service.ApplicationServiceServerImpl, - router *router.RouterImpl, k8sInformer k8sInformer.K8sInformer) *App { + router *router.RouterImpl, k8sInformer k8sInformer.K8sInformer, db *pg.DB) *App { return &App{ Logger: Logger, ServerImpl: ServerImpl, router: router, k8sInformer: k8sInformer, + db: db, } } @@ -67,24 +73,46 @@ func (app *App) Start() { recovery.UnaryServerInterceptor(recoveryOption)), // panic interceptor, should be at last } app.router.InitRouter() - grpcServer := grpc.NewServer(opts...) - - client.RegisterApplicationServiceServer(grpcServer, app.ServerImpl) + app.grpcServer = grpc.NewServer(opts...) + client.RegisterApplicationServiceServer(app.grpcServer, app.ServerImpl) grpc_prometheus.EnableHandlingTimeHistogram() - grpc_prometheus.Register(grpcServer) + grpc_prometheus.Register(app.grpcServer) go func() { - server := &http.Server{Addr: fmt.Sprintf(":%d", httpPort), Handler: app.router.Router} + app.server = &http.Server{Addr: fmt.Sprintf(":%d", httpPort), Handler: app.router.Router} app.router.Router.Use(middlewares.Recovery) - err := server.ListenAndServe() + err := app.server.ListenAndServe() if err != nil { log.Fatal("error in starting http server", err) } }() app.Logger.Infow("starting server on ", "port", port) - - err = grpcServer.Serve(listener) + err = app.grpcServer.Serve(listener) if err != nil { app.Logger.Fatalw("failed to listen: %v", "err", err) } } + +func (app *App) Stop() { + + app.Logger.Infow("kubelink shutdown initiating") + + timeoutContext, _ := context.WithTimeout(context.Background(), 5*time.Second) + app.Logger.Infow("closing router") + err := app.server.Shutdown(timeoutContext) + if err != nil { + app.Logger.Errorw("error in mux router shutdown", "err", err) + } + + // Gracefully stop the gRPC server + app.Logger.Info("Stopping gRPC server...") + app.grpcServer.GracefulStop() + + app.Logger.Infow("closing db connection") + err = app.db.Close() + if err != nil { + app.Logger.Errorw("error in closing db connection", "err", err) + } + + app.Logger.Infow("housekeeping done. exiting now") +} diff --git a/Main.go b/Main.go index cf0e2e27a..dd77d64f9 100644 --- a/Main.go +++ b/Main.go @@ -1,7 +1,11 @@ package main import ( + "fmt" "log" + "os" + "os/signal" + "syscall" ) func main() { @@ -9,5 +13,16 @@ func main() { if err != nil { log.Panic(err) } + // gracefulStop start + var gracefulStop = make(chan os.Signal) + signal.Notify(gracefulStop, syscall.SIGTERM) + signal.Notify(gracefulStop, syscall.SIGINT) + go func() { + sig := <-gracefulStop + fmt.Printf("caught sig: %+v", sig) + app.Stop() + os.Exit(0) + }() + // gracefulStop end app.Start() } diff --git a/wire_gen.go b/wire_gen.go index 26cdc0a4d..823197433 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -57,6 +57,6 @@ func InitializeApp() (*App, error) { applicationServiceServerImpl := service.NewApplicationServiceServerImpl(sugaredLogger, chartRepositoryLocker, helmAppServiceImpl) monitoringRouter := monitoring.NewMonitoringRouter(sugaredLogger) routerImpl := router.NewRouter(sugaredLogger, monitoringRouter) - app := NewApp(sugaredLogger, applicationServiceServerImpl, routerImpl, k8sInformerImpl) + app := NewApp(sugaredLogger, applicationServiceServerImpl, routerImpl, k8sInformerImpl, db) return app, nil }