2026-04-07 12:30:14 +08:00

48 lines
1.5 KiB
Go

package app
import (
"context"
"fmt"
"log/slog"
"gitea.haiyihy.com/hy/chatappuser/internal/config"
"gitea.haiyihy.com/hy/chatappuser/internal/lifecycle"
registerservice "gitea.haiyihy.com/hy/chatappuser/internal/service/register"
grpcserver "gitea.haiyihy.com/hy/chatappuser/internal/transport/grpc"
httpserver "gitea.haiyihy.com/hy/chatappuser/internal/transport/http"
"golang.org/x/sync/errgroup"
)
// Application 聚合用户服务的 HTTP 与 gRPC 服务。
type Application struct {
httpServer *httpserver.Server
grpcServer *grpcserver.Server
hooks lifecycle.Hooks
}
// New 构造用户服务应用。
func New(cfg config.Config, logger *slog.Logger) *Application {
registerHandler := registerservice.New()
registryHooks := lifecycle.NewRegistryHooks(cfg.Registry, logger.With("component", "registry_hooks"))
return &Application{
httpServer: httpserver.New(cfg.App.Name, cfg.App.HTTPAddr, cfg.App.ShutdownTimeout, logger, registryHooks),
grpcServer: grpcserver.New(cfg.App.GRPCAddr, cfg.App.ShutdownTimeout, logger, registerHandler),
hooks: registryHooks,
}
}
// Run 并行启动 HTTP 与 gRPC 服务,收到取消信号后优雅停机。
func (a *Application) Run(ctx context.Context) error {
if err := a.hooks.OnRegister(ctx); err != nil {
return fmt.Errorf("register lifecycle hook: %w", err)
}
group, runCtx := errgroup.WithContext(ctx)
group.Go(func() error {
return a.httpServer.Run(runCtx)
})
group.Go(func() error {
return a.grpcServer.Run(runCtx)
})
return group.Wait()
}