82 lines
2.5 KiB
Go
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
|
|
}
|
|
}
|
|
}
|