75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
package broadcast
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"hyapp/pkg/appcode"
|
|
"hyapp/pkg/logx"
|
|
broadcastdomain "hyapp/services/activity-service/internal/domain/broadcast"
|
|
)
|
|
|
|
type RedPacketWalletOutboxReader interface {
|
|
ListRedPacketCreatedEventsAfter(ctx context.Context, cursor broadcastdomain.RedPacketWalletCursor, batchSize int) ([]broadcastdomain.RedPacketCreatedEvent, error)
|
|
}
|
|
|
|
type RedPacketBroadcastWorkerOptions struct {
|
|
WorkerID string
|
|
PollInterval time.Duration
|
|
BatchSize int
|
|
}
|
|
|
|
// RunRedPacketBroadcastWorker 把 wallet-service 已提交的红包创建事实转成区域飘屏 outbox。
|
|
func (s *Service) RunRedPacketBroadcastWorker(ctx context.Context, reader RedPacketWalletOutboxReader, options RedPacketBroadcastWorkerOptions) {
|
|
if s == nil || reader == nil {
|
|
logx.Warn(ctx, "worker_disabled", slog.String("worker", "red_packet_broadcast"), slog.String("reason", "missing_dependency"))
|
|
return
|
|
}
|
|
if options.PollInterval <= 0 {
|
|
options.PollInterval = 5 * time.Second
|
|
}
|
|
if options.BatchSize <= 0 {
|
|
options.BatchSize = 100
|
|
}
|
|
var cursor broadcastdomain.RedPacketWalletCursor
|
|
for {
|
|
processed, err := s.processRedPacketBroadcastBatch(ctx, reader, &cursor, options.BatchSize)
|
|
if err != nil {
|
|
logx.Error(ctx, "worker_batch_failed", err, slog.String("worker", "red_packet_broadcast"), slog.String("worker_id", options.WorkerID))
|
|
}
|
|
if ctx.Err() != nil {
|
|
return
|
|
}
|
|
if processed >= options.BatchSize {
|
|
continue
|
|
}
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-time.After(options.PollInterval):
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *Service) processRedPacketBroadcastBatch(ctx context.Context, reader RedPacketWalletOutboxReader, cursor *broadcastdomain.RedPacketWalletCursor, batchSize int) (int, error) {
|
|
events, err := reader.ListRedPacketCreatedEventsAfter(ctx, *cursor, batchSize)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
for _, event := range events {
|
|
eventCtx := appcode.WithContext(ctx, event.AppCode)
|
|
if _, err := s.PublishRegionBroadcast(eventCtx, PublishInput{
|
|
EventID: event.EventID,
|
|
BroadcastType: broadcastdomain.TypeRedPacket,
|
|
RegionID: event.RegionID,
|
|
PayloadJSON: event.PayloadJSON,
|
|
}); err != nil {
|
|
return 0, err
|
|
}
|
|
cursor.CreatedAtMS = event.CreatedAtMS
|
|
cursor.EventID = event.EventID
|
|
}
|
|
return len(events), nil
|
|
}
|