@@ -85,7 +85,7 @@ func (d *MDNSDiscovery) Stop() error {
85
85
86
86
// Quit handles the pluggable-discovery QUIT command
87
87
func (d * MDNSDiscovery ) Quit () {
88
- close ( d . entriesChan )
88
+ d . Stop ( )
89
89
}
90
90
91
91
// StartSync handles the pluggable-discovery START_SYNC command
@@ -103,11 +103,8 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
103
103
}
104
104
105
105
d .entriesChan = make (chan * mdns.ServiceEntry , 4 )
106
- var receiver <- chan * mdns.ServiceEntry = d .entriesChan
107
- var sender chan <- * mdns.ServiceEntry = d .entriesChan
108
-
109
106
go func () {
110
- for entry := range receiver {
107
+ for entry := range d . entriesChan {
111
108
port := toDiscoveryPort (entry )
112
109
key := portKey (port )
113
110
if _ , ok := d .portsCache .Get (key ); ! ok {
@@ -118,16 +115,26 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
118
115
}
119
116
}()
120
117
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 )
121
127
params := & mdns.QueryParam {
122
128
Service : mdnsServiceName ,
123
129
Domain : "local" ,
124
130
Timeout : discoveryInterval ,
125
- Entries : sender ,
131
+ Entries : queriesChan ,
126
132
WantUnicastResponse : false ,
127
133
}
128
134
129
135
ctx , cancel := context .WithCancel (context .Background ())
130
136
go func () {
137
+ defer close (queriesChan )
131
138
for {
132
139
if err := mdns .Query (params ); err != nil {
133
140
errorCB ("mdns lookup error: " + err .Error ())
@@ -139,6 +146,13 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
139
146
}
140
147
}
141
148
}()
149
+ go func () {
150
+ for entry := range queriesChan {
151
+ if d .entriesChan != nil {
152
+ d .entriesChan <- entry
153
+ }
154
+ }
155
+ }()
142
156
d .cancelFunc = cancel
143
157
return nil
144
158
}
0 commit comments