package app import ( "context" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" "google.golang.org/grpc" "imageStorage/config" "net" "net/http" "time" ) type App struct { config *config.Config grpcServer *grpc.Server httpServer *gin.Engine httpServerAddr string } type Deps struct { Config *config.Config GrpcServer *grpc.Server HttpServer *gin.Engine } func NewApp(deps Deps) *App { return &App{ config: deps.Config, grpcServer: deps.GrpcServer, httpServer: deps.HttpServer, } } func (app *App) Start(ctx context.Context) error { serverErr := make(chan error, 1) addr := app.config.App.Host + ":" + app.config.App.HttpPort server := &http.Server{ Handler: app.httpServer, Addr: addr, } go func() { log.Info("Starting server on: ", addr) serverErr <- server.ListenAndServe() }() endpoint := net.JoinHostPort(app.config.App.Host, app.config.App.GrpcPort) go func() { listener, err := net.Listen("tcp", endpoint) if err != nil { log.WithField("err", err).Error("gRPC Server | Listener") serverErr <- err } err = app.grpcServer.Serve(listener) if err != nil { log.WithField("err", err).Error("gRPC Server | Serve") serverErr <- err } }() log.Infof("Starting gRPC server on : %s", endpoint) select { case <-ctx.Done(): log.Info("Shutting down server") shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() done := make(chan struct{}) go func() { app.grpcServer.GracefulStop() close(done) }() select { case <-done: log.Info("Server shutdown complete") case <-shutdownCtx.Done(): app.grpcServer.Stop() } return nil case err := <-serverErr: return err } }