@@ -85,7 +85,7 @@ func (d *MDNSDiscovery) Stop() error {
8585
8686// Quit handles the pluggable-discovery QUIT command
8787func (d * MDNSDiscovery ) Quit () {
88- close ( d . entriesChan )
88+ d . Stop ( )
8989}
9090
9191// StartSync handles the pluggable-discovery START_SYNC command
@@ -103,11 +103,8 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
103103 }
104104
105105 d .entriesChan = make (chan * mdns.ServiceEntry , 4 )
106- var receiver <- chan * mdns.ServiceEntry = d .entriesChan
107- var sender chan <- * mdns.ServiceEntry = d .entriesChan
108-
109106 go func () {
110- for entry := range receiver {
107+ for entry := range d . entriesChan {
111108 port := toDiscoveryPort (entry )
112109 key := portKey (port )
113110 if _ , ok := d .portsCache .Get (key ); ! ok {
@@ -118,16 +115,26 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
118115 }
119116 }()
120117
118+ // We use a separate channel to consume the events received
119+ // from Query and send them over to d.entriesChan only if
120+ // it's open.
121+ // If we'd have used d.entriesChan to get the events from
122+ // Query we risk panics cause of sends to a closed channel.
123+ // Query doesn't stop right away when we call d.Stop()
124+ // neither we have to any to do it, we can only wait for it
125+ // to return.
126+ queriesChan := make (chan * mdns.ServiceEntry , 4 )
121127 params := & mdns.QueryParam {
122128 Service : mdnsServiceName ,
123129 Domain : "local" ,
124130 Timeout : discoveryInterval ,
125- Entries : sender ,
131+ Entries : queriesChan ,
126132 WantUnicastResponse : false ,
127133 }
128134
129135 ctx , cancel := context .WithCancel (context .Background ())
130136 go func () {
137+ defer close (queriesChan )
131138 for {
132139 if err := mdns .Query (params ); err != nil {
133140 errorCB ("mdns lookup error: " + err .Error ())
@@ -139,6 +146,13 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
139146 }
140147 }
141148 }()
149+ go func () {
150+ for entry := range queriesChan {
151+ if d .entriesChan != nil {
152+ d .entriesChan <- entry
153+ }
154+ }
155+ }()
142156 d .cancelFunc = cancel
143157 return nil
144158}
0 commit comments