2026-05-14 00:25:02 +08:00

93 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package roomnotice
import (
"context"
"log/slog"
"strings"
"time"
"hyapp/pkg/logx"
)
// RoomNoticeWorkerOptions 控制房间私有通知 worker 的运行参数。
type RoomNoticeWorkerOptions struct {
WorkerID string
PollInterval time.Duration
BatchSize int
LockTTL time.Duration
PublishTimeout time.Duration
MaxRetryCount int
InitialBackoff time.Duration
MaxBackoff time.Duration
}
// RunRoomKickWorker 持续消费 room_outbox 中的 RoomUserKicked 事件。
func (s *Service) RunRoomKickWorker(ctx context.Context, options RoomNoticeWorkerOptions) {
options = normalizeRoomNoticeWorkerOptions(options, s.cfg.NodeID)
ticker := time.NewTicker(options.PollInterval)
defer ticker.Stop()
for {
processed, err := s.ProcessRoomKickNotices(ctx, options)
if err != nil && ctx.Err() == nil {
logx.Error(ctx, "notice_room_kick_batch_failed", err, slog.String("worker_id", options.WorkerID))
}
if processed >= options.BatchSize {
// 批次打满说明有积压,立即继续 drain降低被踢用户退出提示延迟。
continue
}
select {
case <-ctx.Done():
return
case <-ticker.C:
}
}
}
func normalizeRoomNoticeWorkerOptions(options RoomNoticeWorkerOptions, nodeID string) RoomNoticeWorkerOptions {
if strings.TrimSpace(options.WorkerID) == "" {
if strings.TrimSpace(nodeID) == "" {
nodeID = "notice"
}
options.WorkerID = "room-notice-" + nodeID
}
if options.PollInterval <= 0 {
options.PollInterval = time.Second
}
if options.BatchSize <= 0 {
options.BatchSize = 100
}
if options.LockTTL <= 0 {
options.LockTTL = 30 * time.Second
}
if options.PublishTimeout <= 0 {
options.PublishTimeout = 3 * time.Second
}
if options.MaxRetryCount <= 0 {
options.MaxRetryCount = 10
}
if options.InitialBackoff <= 0 {
options.InitialBackoff = 5 * time.Second
}
if options.MaxBackoff <= 0 {
options.MaxBackoff = 5 * time.Minute
}
return options
}
func roomNoticeBackoff(retryCount int, options RoomNoticeWorkerOptions) time.Duration {
if retryCount <= 0 {
return options.InitialBackoff
}
backoff := options.InitialBackoff
for i := 1; i < retryCount; i++ {
if backoff >= options.MaxBackoff/2 {
return options.MaxBackoff
}
backoff *= 2
}
if backoff > options.MaxBackoff {
return options.MaxBackoff
}
return backoff
}