82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
|
|
"chatappgateway/internal/config"
|
|
"chatappgateway/internal/integration/paygrpc"
|
|
"chatappgateway/internal/integration/upstream"
|
|
"chatappgateway/internal/integration/usergrpc"
|
|
"chatappgateway/internal/lifecycle"
|
|
"chatappgateway/internal/service/auth"
|
|
"chatappgateway/internal/service/pay"
|
|
httpserver "chatappgateway/internal/transport/http"
|
|
)
|
|
|
|
// Application 组合网关运行所需的全部组件。
|
|
type Application struct {
|
|
server *httpserver.Server
|
|
closers []io.Closer
|
|
hooks lifecycle.Hooks
|
|
}
|
|
|
|
// New 构造完整应用,包括 gRPC 连接池、业务服务和 HTTP 服务。
|
|
func New(ctx context.Context, cfg config.Config, logger *slog.Logger) (*Application, error) {
|
|
userPool, err := upstream.New(ctx, "ChatAppUser", cfg.GRPC.User)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("build ChatAppUser pool: %w", err)
|
|
}
|
|
|
|
payPool, err := upstream.New(ctx, "ChatAppPay", cfg.GRPC.Pay)
|
|
if err != nil {
|
|
_ = userPool.Close()
|
|
return nil, fmt.Errorf("build ChatAppPay pool: %w", err)
|
|
}
|
|
|
|
userClient := usergrpc.NewWithPool(userPool)
|
|
payClient := paygrpc.NewWithPool(payPool)
|
|
|
|
authService := auth.New(userClient)
|
|
payService := pay.New(payClient)
|
|
registryHooks := lifecycle.NewRegistryHooks(cfg.Registry, logger.With("component", "registry_hooks"))
|
|
readinessChecker := newReadinessGroup(
|
|
namedChecker{
|
|
name: "ChatAppUser",
|
|
check: userPool.Ready,
|
|
},
|
|
namedChecker{
|
|
name: "ChatAppPay",
|
|
check: payPool.Ready,
|
|
},
|
|
)
|
|
server := httpserver.New(cfg.App.Name, cfg.App.HTTPAddr, cfg.App.ShutdownTimeout, logger, authService, payService, readinessChecker, registryHooks)
|
|
|
|
return &Application{
|
|
server: server,
|
|
closers: []io.Closer{userPool, payPool},
|
|
hooks: registryHooks,
|
|
}, nil
|
|
}
|
|
|
|
// Run 启动 HTTP 服务。
|
|
func (a *Application) Run(ctx context.Context) error {
|
|
if err := a.hooks.OnRegister(ctx); err != nil {
|
|
return fmt.Errorf("register lifecycle hook: %w", err)
|
|
}
|
|
return a.server.Run(ctx)
|
|
}
|
|
|
|
// Close 关闭底层 gRPC 连接。
|
|
func (a *Application) Close() error {
|
|
var firstErr error
|
|
for _, closer := range a.closers {
|
|
if err := closer.Close(); err != nil && firstErr == nil {
|
|
firstErr = err
|
|
}
|
|
}
|
|
return firstErr
|
|
}
|