MCPcopy
hub / github.com/tinode/chat / topicUnreg

Method topicUnreg

server/hub.go:392–561  ·  view source on GitHub ↗

topicUnreg deletes or unregisters the topic: Cases: 1. Topic being deleted 1.1 Topic is online 1.1.1 If the requester is the owner or if it's the last sub in a p2p topic (p2p may be sent internally when the last user unsubscribes): 1.1.1.1 Tell topic to stop accepting requests. 1.1.1.2 Hub deletes

(sess *Session, topic string, msg *ClientComMessage, reason int)

Source from the content-addressed store, hash-verified

390// 2. Topic is just being unregistered (topic is going offline)
391// 2.1 Unregister it with no further action
392func (h *Hub) topicUnreg(sess *Session, topic string, msg *ClientComMessage, reason int) error {
393 now := types.TimeNow()
394
395 // TODO: when channel is deleted unsubscribe all devices from channel's FCM topic.
396
397 if reason == StopDeleted {
398 var asUid types.Uid
399 if msg != nil {
400 asUid = types.ParseUserId(msg.AsUser)
401 }
402 // Case 1 (unregister and delete)
403 if t := h.topicGet(topic); t != nil {
404 // Case 1.1: topic is online
405 if (!asUid.IsZero() && t.owner == asUid) || (t.cat == types.TopicCatP2P && t.subsCount() < 2) {
406 // Case 1.1.1: requester is the owner or last sub in a p2p topic
407 t.markPaused(true)
408 hard := true
409 if msg != nil && msg.Del != nil {
410 // Soft-deleting does not make sense for p2p topics.
411 hard = msg.Del.Hard || t.cat == types.TopicCatP2P
412 }
413 if err := store.Topics.Delete(topic, t.isChan, hard); err != nil {
414 t.markPaused(false)
415 if sess != nil {
416 sess.queueOut(ErrUnknownReply(msg, now))
417 }
418 return err
419 }
420 if sess != nil {
421 sess.queueOut(NoErrReply(msg, now))
422 }
423
424 if t.isChan {
425 // Notify channel subscribers that the channel is deleted.
426 sendPush(pushForChanDelete(t.name, now))
427 }
428
429 h.topicDel(topic)
430 t.markDeleted()
431 t.exit <- &shutDown{reason: StopDeleted}
432 statsInc("LiveTopics", -1)
433 } else {
434 // Case 1.1.2: requester is NOT the owner or not empty P2P.
435 msg.MetaWhat = constMsgDelTopic
436 msg.sess = sess
437 t.meta <- msg
438 }
439 } else {
440 // Case 1.2: topic is offline.
441
442 // Is user a channel subscriber? Use chnABC instead of grpABC and get only this user's subscription.
443 var opts *types.QueryOpt
444 if types.IsChannel(msg.Original) {
445 topic = msg.Original
446 opts = &types.QueryOpt{User: asUid}
447 }
448
449 // Get all subscribers of non-channel topics: we need to know how many are left and notify them.

Callers 1

runMethod · 0.95

Calls 15

topicGetMethod · 0.95
IsZeroMethod · 0.95
topicDelMethod · 0.95
StringMethod · 0.95
UserIdMethod · 0.95
TimeNowFunction · 0.92
ParseUserIdFunction · 0.92
IsChannelFunction · 0.92
ErrUnknownReplyFunction · 0.85
NoErrReplyFunction · 0.85
sendPushFunction · 0.85
pushForChanDeleteFunction · 0.85

Tested by

no test coverage detected