Files
im_server/server/im_group_events.go
T

82 lines
2.5 KiB
Go

package main
import (
"encoding/json"
"strconv"
"time"
"github.com/tinode/chat/server/logs"
"github.com/tinode/chat/server/store"
"github.com/tinode/chat/server/store/types"
)
// dispatchIMGroupEvents delivers committed outbox events to online topic
// sessions. Events remain pending when the hub is unavailable or its queue is
// full, so the next successful group mutation retries them.
func dispatchIMGroupEvents(tenantID types.TenantID) {
if tenantID.IsZero() || globals.hub == nil || store.GroupBusiness == nil {
return
}
now := time.Now().UTC().Round(time.Millisecond)
events, err := store.GroupBusiness.ListPendingEvents(tenantID, 100, now)
if err != nil {
logs.Warn.Printf("group outbox: list tenant=%d: %v", tenantID, err)
return
}
for _, event := range events {
members, memberErr := store.Topics.GetUsers(tenantID, event.Topic, &types.QueryOpt{Limit: 1000})
if memberErr != nil {
logs.Warn.Printf("group outbox: list members event=%s: %v", event.EventID, memberErr)
return
}
for _, member := range members {
uid := types.ParseUid(member.User)
if uid.IsZero() {
if decoded, parseErr := strconv.ParseInt(member.User, 10, 64); parseErr == nil && decoded > 0 {
uid = store.EncodeUid(decoded)
}
}
if uid.IsZero() || uid == event.ActorUserID {
continue
}
if err = createIMSystemNotification(tenantID, uid,
stableIMEventID(event.EventID, uid.UserId(), "notification"), event.EventType,
"群聊动态", event.EventType, types.KVMap{"topic": event.Topic}); err != nil {
logs.Warn.Printf("group outbox: create notification event=%s user=%s: %v", event.EventID, uid.UserId(), err)
return
}
}
payload := json.RawMessage(event.Payload)
if len(payload) == 0 {
payload = json.RawMessage(`{}`)
}
from := ""
if !event.ActorUserID.IsZero() {
from = event.ActorUserID.UserId()
}
message := &ServerComMessage{
TenantID: tenantID,
RcptTo: event.Topic,
AsUser: from,
Timestamp: event.CreatedAt,
Info: &MsgServerInfo{
Topic: event.Topic,
From: from,
What: "group",
Event: event.EventType,
Payload: payload,
},
}
select {
case globals.hub.routeSrv <- message:
if err = store.GroupBusiness.MarkEventDelivered(tenantID, event.EventID, now); err != nil {
logs.Warn.Printf("group outbox: mark delivered event=%s: %v", event.EventID, err)
return
}
default:
logs.Warn.Printf("group outbox: hub queue full event=%s", event.EventID)
return
}
}
}