package server import ( "context" "errors" "fmt" "log/slog" "net/http" "github.com/gin-gonic/gin" "go.uber.org/fx" "github.com/looplj/axonhub/internal/log" "github.com/looplj/axonhub/internal/server/api" "github.com/looplj/axonhub/internal/server/backup" "github.com/looplj/axonhub/internal/server/biz" "github.com/looplj/axonhub/internal/server/dependencies" "github.com/looplj/axonhub/internal/server/gc" "github.com/looplj/axonhub/internal/server/gql" "github.com/looplj/axonhub/internal/server/gql/openapi" "github.com/looplj/axonhub/internal/server/middleware" "github.com/looplj/axonhub/internal/tracing" ) func New(config Config) *Server { if !config.Debug { gin.SetMode(gin.ReleaseMode) } engine := gin.New() engine.Use(middleware.Recovery()) return &Server{ Config: config, Engine: engine, } } type Server struct { *gin.Engine Config Config server *http.Server addr string } func (srv *Server) Run() error { log.Info(context.Background(), "run server", log.String("name", srv.Config.Name), log.String("host", srv.Config.Host), log.Int("port", srv.Config.Port), ) addr := fmt.Sprintf("%s:%d", srv.Config.Host, srv.Config.Port) srv.server = &http.Server{ Addr: addr, Handler: srv.Engine, ReadTimeout: srv.Config.ReadTimeout, WriteTimeout: max(srv.Config.RequestTimeout, srv.Config.LLMRequestTimeout), } srv.addr = addr err := srv.server.ListenAndServe() if err != nil { if errors.Is(err, http.ErrServerClosed) { return nil } return err } return nil } func (srv *Server) Shutdown(ctx context.Context) error { return srv.server.Shutdown(ctx) } func Run(opts ...fx.Option) { constructors := []any{ openapi.NewGraphqlHandlers, gql.NewGraphqlHandlers, gc.NewWorker, New, } app := fx.New( append([]fx.Option{ fx.NopLogger, fx.Provide(constructors...), dependencies.Module, biz.Module, backup.Module, api.Module, fx.Invoke(func(cfg log.Config) { log.SetGlobalConfig(cfg) tracing.SetupLogger(log.GetGlobalLogger()) slog.SetDefault(log.GetGlobalLogger().AsSlog()) }), fx.Invoke(func(lc fx.Lifecycle, worker *gc.Worker) { lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { return worker.Start(ctx) }, OnStop: func(ctx context.Context) error { return worker.Stop(ctx) }, }) }), fx.Invoke(SetupRoutes), }, opts...)..., ) app.Run() }