107 lines
3.0 KiB
Go
107 lines
3.0 KiB
Go
package registerreward
|
|
|
|
import "sync"
|
|
|
|
// registerRewardNoticeHub 维护本地调试页订阅的通知监听器。
|
|
// 这里使用进程内广播,目的是在不接入 App IM SDK 的前提下,也能验证
|
|
// “注册成功 -> Go 发奖 -> Go 发 REGISTER_REWARD_GRANTED 通知”这条链路是否打通。
|
|
type registerRewardNoticeHub struct {
|
|
mu sync.RWMutex
|
|
subscribers map[int64]map[chan RegisterRewardNoticeEvent]struct{}
|
|
recent map[int64][]RegisterRewardNoticeEvent
|
|
}
|
|
|
|
// newRegisterRewardNoticeHub 创建进程内通知广播中心。
|
|
func newRegisterRewardNoticeHub() *registerRewardNoticeHub {
|
|
return ®isterRewardNoticeHub{
|
|
subscribers: make(map[int64]map[chan RegisterRewardNoticeEvent]struct{}),
|
|
recent: make(map[int64][]RegisterRewardNoticeEvent),
|
|
}
|
|
}
|
|
|
|
// subscribe 按 userId 订阅注册奖励通知镜像。
|
|
func (h *registerRewardNoticeHub) subscribe(userID int64) (<-chan RegisterRewardNoticeEvent, func()) {
|
|
stream := make(chan RegisterRewardNoticeEvent, 16)
|
|
|
|
h.mu.Lock()
|
|
recent := append([]RegisterRewardNoticeEvent(nil), h.recent[userID]...)
|
|
if _, ok := h.subscribers[userID]; !ok {
|
|
h.subscribers[userID] = make(map[chan RegisterRewardNoticeEvent]struct{})
|
|
}
|
|
h.subscribers[userID][stream] = struct{}{}
|
|
h.mu.Unlock()
|
|
|
|
for _, event := range recent {
|
|
select {
|
|
case stream <- event:
|
|
default:
|
|
}
|
|
}
|
|
|
|
cancel := func() {
|
|
h.mu.Lock()
|
|
defer h.mu.Unlock()
|
|
|
|
group, ok := h.subscribers[userID]
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
if _, exists := group[stream]; exists {
|
|
delete(group, stream)
|
|
close(stream)
|
|
}
|
|
|
|
if len(group) == 0 {
|
|
delete(h.subscribers, userID)
|
|
}
|
|
}
|
|
|
|
return stream, cancel
|
|
}
|
|
|
|
// publish 把通知镜像广播给当前用户的所有本地订阅者。
|
|
// 这里使用非阻塞写入,避免测试页断开或消费变慢时反向卡住正式发奖链路。
|
|
func (h *registerRewardNoticeHub) publish(event RegisterRewardNoticeEvent) {
|
|
if event.UserID <= 0 {
|
|
return
|
|
}
|
|
|
|
h.mu.Lock()
|
|
h.recent[event.UserID] = append(h.recent[event.UserID], event)
|
|
if len(h.recent[event.UserID]) > 10 {
|
|
h.recent[event.UserID] = append([]RegisterRewardNoticeEvent(nil), h.recent[event.UserID][len(h.recent[event.UserID])-10:]...)
|
|
}
|
|
group := h.subscribers[event.UserID]
|
|
targets := make([]chan RegisterRewardNoticeEvent, 0, len(group))
|
|
for stream := range group {
|
|
targets = append(targets, stream)
|
|
}
|
|
h.mu.Unlock()
|
|
|
|
for _, stream := range targets {
|
|
select {
|
|
case stream <- event:
|
|
default:
|
|
}
|
|
}
|
|
}
|
|
|
|
// SubscribeDebugNotices 给本地测试页提供注册奖励通知订阅能力。
|
|
func (s *RegisterRewardService) SubscribeDebugNotices(userID int64) (<-chan RegisterRewardNoticeEvent, func()) {
|
|
if s == nil || s.debug == nil {
|
|
closed := make(chan RegisterRewardNoticeEvent)
|
|
close(closed)
|
|
return closed, func() {}
|
|
}
|
|
return s.debug.subscribe(userID)
|
|
}
|
|
|
|
// publishDebugNotice 把刚刚触发的 REGISTER_REWARD_GRANTED 镜像到本地调试流。
|
|
func (s *RegisterRewardService) publishDebugNotice(event RegisterRewardNoticeEvent) {
|
|
if s == nil || s.debug == nil {
|
|
return
|
|
}
|
|
s.debug.publish(event)
|
|
}
|