feat: use postgres
This commit is contained in:
+42
-69
@@ -18,11 +18,13 @@ import (
|
||||
"galaxy/gateway/internal/grpcapi"
|
||||
"galaxy/gateway/internal/logging"
|
||||
"galaxy/gateway/internal/push"
|
||||
"galaxy/gateway/internal/redisclient"
|
||||
"galaxy/gateway/internal/replay"
|
||||
"galaxy/gateway/internal/restapi"
|
||||
"galaxy/gateway/internal/session"
|
||||
"galaxy/gateway/internal/telemetry"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@@ -132,112 +134,83 @@ func newAuthenticatedGRPCDependencies(ctx context.Context, cfg config.Config, lo
|
||||
return grpcapi.ServerDependencies{}, nil, nil, fmt.Errorf("build authenticated grpc dependencies: load response signer: %w", err)
|
||||
}
|
||||
|
||||
fallbackSessionCache, err := session.NewRedisCache(cfg.SessionCacheRedis)
|
||||
if err != nil {
|
||||
return grpcapi.ServerDependencies{}, nil, nil, fmt.Errorf("build authenticated grpc dependencies: %w", err)
|
||||
}
|
||||
|
||||
replayStore, err := replay.NewRedisStore(cfg.SessionCacheRedis, cfg.ReplayRedis)
|
||||
if err != nil {
|
||||
closeErr := fallbackSessionCache.Close()
|
||||
redisClient := redisclient.NewClient(cfg.Redis)
|
||||
if err := redisclient.InstrumentClient(redisClient, telemetryRuntime); err != nil {
|
||||
closeErr := redisClient.Close()
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
)
|
||||
}
|
||||
closeRedisClient := func() error {
|
||||
err := redisClient.Close()
|
||||
if errors.Is(err, redis.ErrClosed) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if err := redisclient.Ping(ctx, cfg.Redis, redisClient); err != nil {
|
||||
closeErr := closeRedisClient()
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
)
|
||||
}
|
||||
|
||||
fallbackSessionCache, err := session.NewRedisCache(redisClient, cfg.SessionCacheRedis)
|
||||
if err != nil {
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeRedisClient(),
|
||||
)
|
||||
}
|
||||
|
||||
replayStore, err := replay.NewRedisStore(redisClient, cfg.ReplayRedis)
|
||||
if err != nil {
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeRedisClient(),
|
||||
)
|
||||
}
|
||||
|
||||
localSessionCache := session.NewMemoryCache()
|
||||
sessionCache, err := session.NewReadThroughCache(localSessionCache, fallbackSessionCache)
|
||||
if err != nil {
|
||||
closeErr := errors.Join(
|
||||
fallbackSessionCache.Close(),
|
||||
replayStore.Close(),
|
||||
)
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
closeRedisClient(),
|
||||
)
|
||||
}
|
||||
|
||||
pushHub := push.NewHubWithObserver(0, telemetry.NewPushObserver(telemetryRuntime))
|
||||
sessionSubscriber, err := events.NewRedisSessionSubscriberWithObservability(cfg.SessionCacheRedis, cfg.SessionEventsRedis, localSessionCache, pushHub, logger, telemetryRuntime)
|
||||
sessionSubscriber, err := events.NewRedisSessionSubscriberWithObservability(redisClient, cfg.SessionCacheRedis, cfg.SessionEventsRedis, localSessionCache, pushHub, logger, telemetryRuntime)
|
||||
if err != nil {
|
||||
closeErr := errors.Join(
|
||||
fallbackSessionCache.Close(),
|
||||
replayStore.Close(),
|
||||
)
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
closeRedisClient(),
|
||||
)
|
||||
}
|
||||
|
||||
clientEventSubscriber, err := events.NewRedisClientEventSubscriberWithObservability(cfg.SessionCacheRedis, cfg.ClientEventsRedis, pushHub, logger, telemetryRuntime)
|
||||
clientEventSubscriber, err := events.NewRedisClientEventSubscriberWithObservability(redisClient, cfg.SessionCacheRedis, cfg.ClientEventsRedis, pushHub, logger, telemetryRuntime)
|
||||
if err != nil {
|
||||
closeErr := errors.Join(
|
||||
fallbackSessionCache.Close(),
|
||||
replayStore.Close(),
|
||||
sessionSubscriber.Close(),
|
||||
)
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
closeRedisClient(),
|
||||
)
|
||||
}
|
||||
|
||||
userRoutes, closeUserServiceRoutes, err := userservice.NewRoutes(cfg.UserService.BaseURL)
|
||||
if err != nil {
|
||||
closeErr := errors.Join(
|
||||
fallbackSessionCache.Close(),
|
||||
replayStore.Close(),
|
||||
sessionSubscriber.Close(),
|
||||
clientEventSubscriber.Close(),
|
||||
)
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: user service routes: %w", err),
|
||||
closeErr,
|
||||
closeRedisClient(),
|
||||
)
|
||||
}
|
||||
|
||||
cleanup := func() error {
|
||||
return errors.Join(
|
||||
fallbackSessionCache.Close(),
|
||||
replayStore.Close(),
|
||||
sessionSubscriber.Close(),
|
||||
clientEventSubscriber.Close(),
|
||||
closeUserServiceRoutes(),
|
||||
)
|
||||
}
|
||||
|
||||
if err := fallbackSessionCache.Ping(ctx); err != nil {
|
||||
closeErr := cleanup()
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
)
|
||||
}
|
||||
|
||||
if err := replayStore.Ping(ctx); err != nil {
|
||||
closeErr := cleanup()
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
)
|
||||
}
|
||||
|
||||
if err := sessionSubscriber.Ping(ctx); err != nil {
|
||||
closeErr := cleanup()
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
)
|
||||
}
|
||||
|
||||
if err := clientEventSubscriber.Ping(ctx); err != nil {
|
||||
closeErr := cleanup()
|
||||
return grpcapi.ServerDependencies{}, nil, nil, errors.Join(
|
||||
fmt.Errorf("build authenticated grpc dependencies: %w", err),
|
||||
closeErr,
|
||||
closeRedisClient(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"galaxy/gateway/internal/config"
|
||||
"galaxy/gateway/internal/restapi"
|
||||
"galaxy/redisconn"
|
||||
|
||||
"github.com/alicebob/miniredis/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -22,6 +23,16 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func testRedisConn(masterAddr string, opTimeout time.Duration) redisconn.Config {
|
||||
cfg := redisconn.DefaultConfig()
|
||||
cfg.MasterAddr = masterAddr
|
||||
cfg.Password = "integration"
|
||||
if opTimeout > 0 {
|
||||
cfg.OperationTimeout = opTimeout
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func TestNewPublicRESTDependencies(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -102,8 +113,8 @@ func TestNewAuthenticatedGRPCDependencies(t *testing.T) {
|
||||
{
|
||||
name: "success",
|
||||
cfg: config.Config{
|
||||
Redis: testRedisConn(server.Addr(), 250*time.Millisecond),
|
||||
SessionCacheRedis: config.SessionCacheRedisConfig{
|
||||
Addr: server.Addr(),
|
||||
KeyPrefix: "gateway:session:",
|
||||
LookupTimeout: 250 * time.Millisecond,
|
||||
},
|
||||
@@ -125,8 +136,9 @@ func TestNewAuthenticatedGRPCDependencies(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid redis config",
|
||||
name: "invalid session cache key prefix",
|
||||
cfg: config.Config{
|
||||
Redis: testRedisConn(server.Addr(), 250*time.Millisecond),
|
||||
SessionCacheRedis: config.SessionCacheRedisConfig{
|
||||
LookupTimeout: 250 * time.Millisecond,
|
||||
},
|
||||
@@ -146,13 +158,13 @@ func TestNewAuthenticatedGRPCDependencies(t *testing.T) {
|
||||
PrivateKeyPEMPath: responseSignerPEMPath,
|
||||
},
|
||||
},
|
||||
wantErr: "redis addr must not be empty",
|
||||
wantErr: "redis key prefix must not be empty",
|
||||
},
|
||||
{
|
||||
name: "startup ping failure",
|
||||
cfg: config.Config{
|
||||
Redis: testRedisConn(unusedTCPAddr(t), 100*time.Millisecond),
|
||||
SessionCacheRedis: config.SessionCacheRedisConfig{
|
||||
Addr: unusedTCPAddr(t),
|
||||
KeyPrefix: "gateway:session:",
|
||||
LookupTimeout: 100 * time.Millisecond,
|
||||
},
|
||||
@@ -172,13 +184,13 @@ func TestNewAuthenticatedGRPCDependencies(t *testing.T) {
|
||||
PrivateKeyPEMPath: responseSignerPEMPath,
|
||||
},
|
||||
},
|
||||
wantErr: "ping redis session cache",
|
||||
wantErr: "ping redis",
|
||||
},
|
||||
{
|
||||
name: "invalid replay config",
|
||||
cfg: config.Config{
|
||||
Redis: testRedisConn(server.Addr(), 250*time.Millisecond),
|
||||
SessionCacheRedis: config.SessionCacheRedisConfig{
|
||||
Addr: server.Addr(),
|
||||
KeyPrefix: "gateway:session:",
|
||||
LookupTimeout: 250 * time.Millisecond,
|
||||
},
|
||||
@@ -202,8 +214,8 @@ func TestNewAuthenticatedGRPCDependencies(t *testing.T) {
|
||||
{
|
||||
name: "invalid client event config",
|
||||
cfg: config.Config{
|
||||
Redis: testRedisConn(server.Addr(), 250*time.Millisecond),
|
||||
SessionCacheRedis: config.SessionCacheRedisConfig{
|
||||
Addr: server.Addr(),
|
||||
KeyPrefix: "gateway:session:",
|
||||
LookupTimeout: 250 * time.Millisecond,
|
||||
},
|
||||
@@ -227,8 +239,8 @@ func TestNewAuthenticatedGRPCDependencies(t *testing.T) {
|
||||
{
|
||||
name: "missing response signer path",
|
||||
cfg: config.Config{
|
||||
Redis: testRedisConn(server.Addr(), 250*time.Millisecond),
|
||||
SessionCacheRedis: config.SessionCacheRedisConfig{
|
||||
Addr: server.Addr(),
|
||||
KeyPrefix: "gateway:session:",
|
||||
LookupTimeout: 250 * time.Millisecond,
|
||||
},
|
||||
@@ -250,8 +262,8 @@ func TestNewAuthenticatedGRPCDependencies(t *testing.T) {
|
||||
{
|
||||
name: "invalid response signer pem",
|
||||
cfg: config.Config{
|
||||
Redis: testRedisConn(server.Addr(), 250*time.Millisecond),
|
||||
SessionCacheRedis: config.SessionCacheRedisConfig{
|
||||
Addr: server.Addr(),
|
||||
KeyPrefix: "gateway:session:",
|
||||
LookupTimeout: 250 * time.Millisecond,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user