@@ -3,6 +3,7 @@ package nsqd
33import (
44 "bytes"
55 "encoding/json"
6+ "fmt"
67 "net"
78 "os"
89 "strconv"
@@ -12,6 +13,17 @@ import (
1213 "github.com/nsqio/nsq/internal/version"
1314)
1415
16+ const (
17+ NotifyTypeRegistration = iota
18+ NotifyTypeUnRegistration
19+ NotifyTypeStateUpdate
20+ )
21+
22+ type notifyContext struct {
23+ notifyType int
24+ v interface {}
25+ }
26+
1527func connectCallback (n * NSQD , hostname string ) func (* lookupPeer ) {
1628 return func (lp * lookupPeer ) {
1729 ci := make (map [string ]interface {})
@@ -53,11 +65,26 @@ func connectCallback(n *NSQD, hostname string) func(*lookupPeer) {
5365 n .RLock ()
5466 for _ , topic := range n .topicMap {
5567 topic .RLock ()
56- if len (topic .channelMap ) == 0 {
57- commands = append (commands , nsq .Register (topic .name , "" ))
58- } else {
59- for _ , channel := range topic .channelMap {
60- commands = append (commands , nsq .Register (channel .topicName , channel .name ))
68+ commands = append (commands , nsq .Register (topic .name , "" ))
69+ topicPaused := topic .IsPaused ()
70+ if topicPaused { //sync state when topic paused
71+ command , err := nsq .SyncState (topic .name , "" , map [string ]interface {}{"paused" : topicPaused })
72+ if err != nil {
73+ n .logf (LOG_ERROR , "LOOKUPD(%s): SyncState - %s" , lp , err )
74+ } else {
75+ commands = append (commands , command )
76+ }
77+ }
78+ for _ , channel := range topic .channelMap {
79+ commands = append (commands , nsq .Register (channel .topicName , channel .name ))
80+ channelPaused := channel .IsPaused ()
81+ if channelPaused { //sync state when channel paused
82+ command , err := nsq .SyncState (channel .topicName , channel .name , map [string ]interface {}{"paused" : channelPaused })
83+ if err != nil {
84+ n .logf (LOG_ERROR , "LOOKUPD(%s): SyncState - %s" , lp , err )
85+ continue
86+ }
87+ commands = append (commands , command )
6188 }
6289 }
6390 topic .RUnlock ()
@@ -118,29 +145,61 @@ func (n *NSQD) lookupLoop() {
118145 }
119146 case val := <- n .notifyChan :
120147 var cmd * nsq.Command
148+ var err error
121149 var branch string
122-
123- switch val .(type ) {
124- case * Channel :
125- // notify all nsqlookupds that a new channel exists, or that it's removed
126- branch = "channel"
127- channel := val .(* Channel )
128- if channel .Exiting () == true {
129- cmd = nsq .UnRegister (channel .topicName , channel .name )
130- } else {
150+ notifyCtx , ok := val .(notifyContext )
151+ if ! ok {
152+ panic ("non-notifyContext sent to notifyChan - should never happen" )
153+ }
154+ switch notifyCtx .notifyType {
155+ case NotifyTypeRegistration :
156+ switch notifyCtx .v .(type ) {
157+ case * Channel :
158+ // notify all nsqlookupds that a new channel exists
159+ branch = "channel"
160+ channel := notifyCtx .v .(* Channel )
131161 cmd = nsq .Register (channel .topicName , channel .name )
162+ case * Topic :
163+ // notify all nsqlookupds that a new topic exists
164+ branch = "topic"
165+ topic := notifyCtx .v .(* Topic )
166+ cmd = nsq .Register (topic .name , "" )
132167 }
133- case * Topic :
134- // notify all nsqlookupds that a new topic exists, or that it's removed
135- branch = "topic"
136- topic := val .(* Topic )
137- if topic .Exiting () == true {
168+ case NotifyTypeUnRegistration :
169+ switch notifyCtx .v .(type ) {
170+ case * Channel :
171+ // notify all nsqlookupds that a new channel removed
172+ branch = "channel"
173+ channel := notifyCtx .v .(* Channel )
174+ cmd = nsq .UnRegister (channel .topicName , channel .name )
175+ case * Topic :
176+ // notify all nsqlookupds that a new topic removed
177+ branch = "topic"
178+ topic := notifyCtx .v .(* Topic )
138179 cmd = nsq .UnRegister (topic .name , "" )
139- } else {
140- cmd = nsq .Register (topic .name , "" )
141180 }
181+ case NotifyTypeStateUpdate :
182+ switch notifyCtx .v .(type ) {
183+ case * Channel :
184+ // notify all nsqlookupds that channel state changed
185+ branch = "channel"
186+ channel := notifyCtx .v .(* Channel )
187+ cmd , err = nsq .SyncState (channel .topicName , channel .name , map [string ]interface {}{"paused" : channel .IsPaused ()})
188+ if err != nil {
189+ n .logf (LOG_ERROR , "NSQD: build cmd err: %s" , err )
190+ }
191+ case * Topic :
192+ // notify all nsqlookupds that topic state changed
193+ branch = "topic"
194+ topic := notifyCtx .v .(* Topic )
195+ cmd , err = nsq .SyncState (topic .name , "" , map [string ]interface {}{"paused" : topic .IsPaused ()})
196+ if err != nil {
197+ n .logf (LOG_ERROR , "NSQD: build cmd err: %s" , err )
198+ }
199+ }
200+ default :
201+ panic (fmt .Sprintf ("unknown notifyType in notifyContext: %d, should never happen" , notifyCtx .notifyType ))
142202 }
143-
144203 for _ , lookupPeer := range lookupPeers {
145204 n .logf (LOG_INFO , "LOOKUPD(%s): %s %s" , lookupPeer , branch , cmd )
146205 _ , err := lookupPeer .Command (cmd )
0 commit comments