fix p2p permission refresh during load tests

This commit is contained in:
richjohnrambo
2026-09-27 12:53:09 +08:00
parent a57d1e8d4a
commit f9f7321b11
9 changed files with 269 additions and 15 deletions
+30 -1
View File
@@ -678,6 +678,10 @@ func (t *Topic) handleServerMsg(msg *ServerComMessage) {
// Ignore message - the topic is paused or being deleted.
return
}
if msg.Info != nil && msg.Info.What == "p2p" && msg.Info.Event == p2pPermissionsRefreshedEvent {
t.handleP2PPermissionsRefresh(msg.Info)
return
}
if msg.Pres != nil {
t.handlePresence(msg)
} else if msg.Info != nil || msg.Data != nil {
@@ -700,6 +704,24 @@ func (t *Topic) handleServerMsg(msg *ServerComMessage) {
}
}
func (t *Topic) handleP2PPermissionsRefresh(info *MsgServerInfo) {
if t.cat != types.TopicCatP2P || t.isProxy {
return
}
var payload p2pPermissionsPayload
if err := json.Unmarshal(info.Payload, &payload); err != nil {
logs.Warn.Printf("topic[%s]: failed to decode p2p permissions refresh: %v", t.name, err)
return
}
uids := make([]types.Uid, 0, len(payload.UserIDs))
for _, raw := range payload.UserIDs {
if uid := types.ParseUserId(raw); !uid.IsZero() {
uids = append(uids, uid)
}
}
t.refreshPerUserFromDB(types.ZeroUid, uids...)
}
// flexUID accepts a JSON string or number representation of a user id: the
// HTTP interface publishes base32 user id strings, while Kafka admin commands
// publish numeric database ids.
@@ -1282,8 +1304,15 @@ func (t *Topic) saveAndBroadcastMessage(msg *ClientComMessage, asUid types.Uid,
return types.ErrPermissionDenied
}
} else {
// EnsureP2P may have repaired the subscription in the database while this
// topic was already loaded. Reload once on denied P2P publishes so a lost
// or delayed refresh event cannot leave the conversation permanently stale.
if t.cat == types.TopicCatP2P && userFound && !(pud.modeWant & pud.modeGiven).IsWriter() && store.Subs != nil {
t.refreshPerUserFromDB(asUid, asUid)
pud, userFound = t.perUser[asUid]
}
// If it's not 'sys' check write permission.
if !(pud.modeWant & pud.modeGiven).IsWriter() {
if !userFound || !(pud.modeWant & pud.modeGiven).IsWriter() {
msg.sess.queueOut(ErrPermissionDenied(msg.Id, t.original(asUid), msg.Timestamp))
return types.ErrPermissionDenied
}