2026-07-04 01:53:10 +08:00

47 lines
1.8 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 broadcast
import (
"context"
"log/slog"
"time"
"hyapp/pkg/logx"
)
// RunWorker 先按需补齐播报群,再持续拉取持久化 outbox 投递腾讯 IM。
// 该 worker 只在 broadcast.enabled 且 tencent_im.enabled 时启动,本地默认关闭,防止开发环境误发真实 IM。
func (s *Service) RunWorker(ctx context.Context, options WorkerOptions) {
options = normalizeWorkerOptions(options, s.cfg)
if s.cfg.EnsureGroupsOnStartup {
// 建群失败不退出进程:下一轮部署/定时任务可继续补偿,已经入队的消息仍保留在 MySQL。
s.reconcileBroadcastGroups(ctx, options)
}
ticker := time.NewTicker(options.PollInterval)
defer ticker.Stop()
lastReconcile := s.now()
for {
// 定时 reconcile 兜底新区域上线和启动时腾讯 REST 抖动:只跑一次的启动补偿失败后,
// 缺失的区域群会让该区域全部播报静默 failed 沉底,不能等下一次部署才补群。
if s.cfg.EnsureGroupsInterval > 0 && s.now().Sub(lastReconcile) >= s.cfg.EnsureGroupsInterval {
lastReconcile = s.now()
s.reconcileBroadcastGroups(ctx, options)
}
if _, err := s.ProcessPendingBroadcasts(ctx, options); err != nil && ctx.Err() == nil {
// 批处理失败只影响当前轮询outbox 记录没有被删除,下一轮会按锁和重试状态重新处理。
logx.Error(ctx, "broadcast_outbox_batch_failed", err, slog.String("worker_id", options.WorkerID))
}
select {
case <-ctx.Done():
return
case <-ticker.C:
}
}
}
func (s *Service) reconcileBroadcastGroups(ctx context.Context, options WorkerOptions) {
if _, err := s.EnsureBroadcastGroups(ctx); err != nil && ctx.Err() == nil {
logx.Error(ctx, "broadcast_group_reconcile_failed", err, slog.String("worker_id", options.WorkerID))
}
}