fix: move group push work off topic loop

This commit is contained in:
richjohnrambo
2026-09-30 10:01:59 +08:00
parent da8efb6e38
commit 9f30995787
11 changed files with 455 additions and 24 deletions
+43
View File
@@ -111,6 +111,7 @@ type groupMessageRuntime interface {
RefreshUserPresence(tenantID types.TenantID, uid types.Uid, sid, nodeID string) error
MarkUserOffline(tenantID types.TenantID, uid types.Uid, sid, nodeID string) (int, error)
GetUserPresence(tenantID types.TenantID, uid types.Uid) (*UserPresence, error)
GetUsersPresence(tenantID types.TenantID, uids []types.Uid) (map[types.Uid]*UserPresence, error)
MarkTopicMemberOnline(tenantID types.TenantID, topic string, uid types.Uid, nodeID string) error
MarkTopicMemberOffline(tenantID types.TenantID, topic string, uid types.Uid, nodeID string) error
GetTopicNodeOnlineMembers(tenantID types.TenantID, topic, nodeID string) ([]types.Uid, error)
@@ -339,6 +340,14 @@ func GetUserPresence(tenantID types.TenantID, uid types.Uid) (*UserPresence, err
return groupMsgRuntime.GetUserPresence(tenantID, uid)
}
func GetUsersPresence(tenantID types.TenantID, uids []types.Uid) (map[types.Uid]*UserPresence, error) {
result := make(map[types.Uid]*UserPresence, len(uids))
if groupMsgRuntime == nil || !tenantID.IsValid() || len(uids) == 0 {
return result, nil
}
return groupMsgRuntime.GetUsersPresence(tenantID, uids)
}
func UserPresenceEnabled() bool {
return groupMsgRuntime != nil
}
@@ -1027,6 +1036,40 @@ func (r *redisGroupMessageRuntime) GetUserPresence(tenantID types.TenantID, uid
return presence, nil
}
func (r *redisGroupMessageRuntime) GetUsersPresence(tenantID types.TenantID, uids []types.Uid) (map[types.Uid]*UserPresence, error) {
result := make(map[types.Uid]*UserPresence, len(uids))
if len(uids) == 0 {
return result, nil
}
ctx := context.Background()
pipe := r.client.Pipeline()
commands := make(map[types.Uid]*redis.MapStringStringCmd, len(uids))
for _, uid := range uids {
if !uid.IsZero() {
commands[uid] = pipe.HGetAll(ctx, r.presenceUserKey(tenantID, uid))
}
}
if _, err := pipe.Exec(ctx); err != nil && err != redis.Nil {
return nil, err
}
for uid, command := range commands {
raw, err := command.Result()
if err != nil && err != redis.Nil {
return nil, err
}
presence := &UserPresence{}
if len(raw) > 0 {
presence.Online = raw["online"] == "1"
presence.NodeID = raw["node_id"]
presence.SessionCount, _ = strconv.Atoi(raw["session_count"])
presence.LastActiveAt, _ = time.Parse(time.RFC3339Nano, raw["last_active_at"])
presence.LastSeenAt, _ = time.Parse(time.RFC3339Nano, raw["last_seen_at"])
}
result[uid] = presence
}
return result, nil
}
func (r *redisGroupMessageRuntime) MarkTopicMemberOnline(tenantID types.TenantID, topic string, uid types.Uid, nodeID string) error {
if nodeID == "" {
nodeID = "local"