Fixed router idempotency. Return registry.ErrWatchStopped from mdns reg
This commit is contained in:
parent
cff46c3fd8
commit
f6e064cdbd
@ -134,12 +134,10 @@ func (r *router) manageServiceRoutes(w registry.Watcher, metric int) error {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
res, err := w.Next()
|
res, err := w.Next()
|
||||||
if err == registry.ErrWatcherStopped {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err != registry.ErrWatcherStopped {
|
||||||
watchErr = err
|
watchErr = err
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,14 +179,13 @@ func (r *router) watchTable(w Watcher) error {
|
|||||||
|
|
||||||
var watchErr error
|
var watchErr error
|
||||||
|
|
||||||
|
exit:
|
||||||
for {
|
for {
|
||||||
event, err := w.Next()
|
event, err := w.Next()
|
||||||
if err == ErrWatcherStopped {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err != ErrWatcherStopped {
|
||||||
watchErr = err
|
watchErr = err
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,23 +197,21 @@ func (r *router) watchTable(w Watcher) error {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case <-r.exit:
|
case <-r.exit:
|
||||||
return nil
|
break exit
|
||||||
case r.advertChan <- u:
|
case r.advertChan <- u:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// close the advertisement channel
|
||||||
|
close(r.advertChan)
|
||||||
|
|
||||||
return watchErr
|
return watchErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// manageStatus manages router status
|
// watchError watches router errors
|
||||||
func (r *router) manageStatus(errChan <-chan error) {
|
func (r *router) watchError(errChan <-chan error) {
|
||||||
defer r.wg.Done()
|
defer r.wg.Done()
|
||||||
|
|
||||||
r.Lock()
|
|
||||||
r.status.Code = Running
|
|
||||||
r.status.Error = nil
|
|
||||||
r.Unlock()
|
|
||||||
|
|
||||||
var code StatusCode
|
var code StatusCode
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -229,14 +224,13 @@ func (r *router) manageStatus(errChan <-chan error) {
|
|||||||
|
|
||||||
r.Lock()
|
r.Lock()
|
||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
r.status.Code = code
|
status := Status{
|
||||||
r.status.Error = err
|
Code: code,
|
||||||
|
Error: err,
|
||||||
// close the advertise channel
|
}
|
||||||
close(r.advertChan)
|
r.status = status
|
||||||
|
|
||||||
// stop the router if some error happened
|
// stop the router if some error happened
|
||||||
// this will notify all watcher goroutines to stop
|
|
||||||
if err != nil && code != Stopped {
|
if err != nil && code != Stopped {
|
||||||
close(r.exit)
|
close(r.exit)
|
||||||
}
|
}
|
||||||
@ -303,7 +297,14 @@ func (r *router) Advertise() (<-chan *Update, error) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
r.wg.Add(1)
|
r.wg.Add(1)
|
||||||
go r.manageStatus(errChan)
|
go r.watchError(errChan)
|
||||||
|
|
||||||
|
// mark router as running and set its Error to nil
|
||||||
|
status := Status{
|
||||||
|
Code: Running,
|
||||||
|
Error: nil,
|
||||||
|
}
|
||||||
|
r.status = status
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.advertChan, nil
|
return r.advertChan, nil
|
||||||
@ -338,15 +339,19 @@ func (r *router) Status() Status {
|
|||||||
// Stop stops the router
|
// Stop stops the router
|
||||||
func (r *router) Stop() error {
|
func (r *router) Stop() error {
|
||||||
r.RLock()
|
r.RLock()
|
||||||
defer r.RUnlock()
|
|
||||||
|
|
||||||
// only close the channel if the router is running
|
// only close the channel if the router is running
|
||||||
if r.status.Code == Running {
|
if r.status.Code == Running {
|
||||||
// notify all goroutines to finish
|
// notify all goroutines to finish
|
||||||
close(r.exit)
|
close(r.exit)
|
||||||
|
}
|
||||||
|
r.RUnlock()
|
||||||
|
|
||||||
|
// drain the advertise channel
|
||||||
|
for range r.advertChan {
|
||||||
|
}
|
||||||
|
|
||||||
// wait for all goroutines to finish
|
// wait for all goroutines to finish
|
||||||
r.wg.Wait()
|
r.wg.Wait()
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrWatcherStopped is returned when routing table watcher has been stopped
|
// ErrWatcherStopped is returned when routing table watcher has been stopped
|
||||||
ErrWatcherStopped = errors.New("routing table watcher stopped")
|
ErrWatcherStopped = errors.New("watcher stopped")
|
||||||
)
|
)
|
||||||
|
|
||||||
// EventType defines routing table event
|
// EventType defines routing table event
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package registry
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/micro/mdns"
|
"github.com/micro/mdns"
|
||||||
@ -63,7 +62,7 @@ func (m *mdnsWatcher) Next() (*Result, error) {
|
|||||||
Service: service,
|
Service: service,
|
||||||
}, nil
|
}, nil
|
||||||
case <-m.exit:
|
case <-m.exit:
|
||||||
return nil, errors.New("watcher stopped")
|
return nil, ErrWatcherStopped
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user