64 lines
2.3 KiB
Go
64 lines
2.3 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"hyapp/pkg/outboxpartition"
|
|
"hyapp/pkg/outboxreplay"
|
|
"hyapp/pkg/rocketmqx"
|
|
servicemq "hyapp/pkg/servicekit/mq"
|
|
"hyapp/services/game-service/internal/config"
|
|
mysqlstorage "hyapp/services/game-service/internal/storage/mysql"
|
|
)
|
|
|
|
// ReplayGameOutboxOnce runs the ordinary game fact publisher for one App and a
|
|
// process-wide hard limit. It opens no gRPC listener and no downstream service
|
|
// connection, so an empty partition is a read-only no-op apart from MQ producer
|
|
// registration.
|
|
func ReplayGameOutboxOnce(ctx context.Context, cfg config.Config, scope outboxreplay.Scope) (outboxreplay.Result, error) {
|
|
validatedScope, err := outboxreplay.NewScope(scope.AppCode, scope.Limit, 500)
|
|
if err != nil {
|
|
return outboxreplay.Result{}, err
|
|
}
|
|
if !cfg.RocketMQ.GameOutbox.Enabled {
|
|
return outboxreplay.Result{}, errors.New("game RocketMQ outbox is not enabled")
|
|
}
|
|
repository, err := mysqlstorage.Open(ctx, cfg.MySQLDSN)
|
|
if err != nil {
|
|
return outboxreplay.Result{}, err
|
|
}
|
|
defer func() { _ = repository.Close() }()
|
|
producer, err := rocketmqx.NewProducer(rocketMQProducerConfig(cfg.RocketMQ))
|
|
if err != nil {
|
|
return outboxreplay.Result{}, err
|
|
}
|
|
if err := servicemq.StartProducers([]*rocketmqx.Producer{producer}); err != nil {
|
|
return outboxreplay.Result{}, err
|
|
}
|
|
defer servicemq.ShutdownProducers([]*rocketmqx.Producer{producer})
|
|
|
|
replayConfig := cfg
|
|
replayConfig.OutboxWorker.BatchSize = 1
|
|
replayConfig.OutboxWorker.AppCodes = []string{validatedScope.AppCode}
|
|
replayCtx, cancel := context.WithCancel(ctx)
|
|
defer cancel()
|
|
replayApp := &App{
|
|
repo: repository,
|
|
outboxProducer: producer,
|
|
outboxPartitions: outboxpartition.New(replayConfig.OutboxWorker.AppCodes, outboxpartition.DefaultDiscoveryRefreshInterval),
|
|
outboxCtx: replayCtx,
|
|
outboxCancel: cancel,
|
|
cfg: replayConfig,
|
|
}
|
|
workerID := fmt.Sprintf("ops-game-outbox-%s-%d", validatedScope.AppCode, time.Now().UTC().UnixMilli())
|
|
return outboxreplay.Run(ctx, validatedScope, func(context.Context) (int, error) {
|
|
// processOutboxBatch derives the same worker prefix as the live service;
|
|
// attach the unique run ID to NodeID so lock ownership remains auditable.
|
|
replayApp.cfg.NodeID = workerID
|
|
return replayApp.processOutboxBatch()
|
|
})
|
|
}
|