Slide 10
Slide 10 text
func (n *Node) Subscribe(s *Session, msg *common.Message) (*common.CommandResult, error) {
s.smu.Lock()
if ok := s.subscriptions.HasChannel(msg.Identifier); ok {
s.smu.Unlock()
return nil, fmt.Errorf("already subscribed to %s", msg.Identifier)
}
res, err := n.controller.Subscribe(s.closeCtx, s.GetID(), s.env, s.GetIdentifiers(), msg.Identifier)
if s.IsClosed() {
s.Log.Debug("skip subscribe result: closed")
return nil, nil
}
if res == nil && err == nil {
return nil, nil
}
s.Log.Debug("controller subscribe", "response", res, "err", err)
var confirmed bool
if err != nil {
if res == nil || res.Status == common.ERROR {
return nil, errorx.Decorate(err, "subscribe failed for %s", msg.Identifier)
}
} else if res.Status == common.SUCCESS {
confirmed = true
s.subscriptions.AddChannel(msg.Identifier)
s.Log.Debug("subscribed", "identifier", msg.Identifier)
} else {
s.Log.Debug("subscription rejected", "identifier", msg.Identifier)
}
s.smu.Unlock()
if res != nil {
n.handleCommandReply(s, msg, res)
n.markDisconnectable(s, res.DisconnectInterest)
}
if confirmed {
if s.IsResumeable() {
if berr := n.broker.CommitSession(s.GetID(), s); berr != nil {
s.Log.Error("failed to persist session in cache", "error", berr)
}
}
if msg.History.Since > 0 || msg.History.Streams != nil {
if err := n.History(s, msg); err != nil {
s.Log.Warn("couldn't retrieve history", "identifier", msg.Identifier, "error", err)
}
}
if msg.Presence != nil {
if err := n.handlePresenceReply(s, msg.Identifier, common.PresenceJoinType, msg.Presence); err != nil {
s.Log.Warn("couldn't process presence join", "identifier", msg.Identifier, "error", err)
}
}
}
return res, nil
}