p2p/discover: cancel lookups on shutdown

This commit is contained in:
Felix Lange 2019-01-24 08:50:07 +01:00
parent 17723a5294
commit 3ec792268c

View file

@ -75,6 +75,8 @@ type Table struct {
net transport net transport
refreshReq chan chan struct{} refreshReq chan chan struct{}
initDone chan struct{} initDone chan struct{}
closeOnce sync.Once
closeReq chan struct{} closeReq chan struct{}
closed chan struct{} closed chan struct{}
@ -180,16 +182,14 @@ func (tab *Table) ReadRandomNodes(buf []*enode.Node) (n int) {
// Close terminates the network listener and flushes the node database. // Close terminates the network listener and flushes the node database.
func (tab *Table) Close() { func (tab *Table) Close() {
tab.closeOnce.Do(func() {
if tab.net != nil { if tab.net != nil {
tab.net.close() tab.net.close()
} }
// Wait for loop to end.
select { close(tab.closeReq)
case <-tab.closed: <-tab.closed
// already closed. })
case tab.closeReq <- struct{}{}:
<-tab.closed // wait for refreshLoop to end.
}
} }
// setFallbackNodes sets the initial points of contact. These nodes // setFallbackNodes sets the initial points of contact. These nodes
@ -290,13 +290,17 @@ func (tab *Table) lookup(targetKey encPubkey, refreshIfEmpty bool) []*node {
// we have asked all closest nodes, stop the search // we have asked all closest nodes, stop the search
break break
} }
// wait for the next reply select {
for _, n := range <-reply { case nodes := <-reply:
for _, n := range nodes {
if n != nil && !seen[n.ID()] { if n != nil && !seen[n.ID()] {
seen[n.ID()] = true seen[n.ID()] = true
result.push(n, bucketSize) result.push(n, bucketSize)
} }
} }
case <-tab.closeReq:
return nil // shutdown, no need to continue.
}
pendingQueries-- pendingQueries--
} }
return result.entries return result.entries
@ -305,7 +309,11 @@ func (tab *Table) lookup(targetKey encPubkey, refreshIfEmpty bool) []*node {
func (tab *Table) findnode(n *node, targetKey encPubkey, reply chan<- []*node) { func (tab *Table) findnode(n *node, targetKey encPubkey, reply chan<- []*node) {
fails := tab.db.FindFails(n.ID()) fails := tab.db.FindFails(n.ID())
r, err := tab.net.findnode(n.ID(), n.addr(), targetKey) r, err := tab.net.findnode(n.ID(), n.addr(), targetKey)
if err != nil || len(r) == 0 { if err == errClosed {
// Avoid recording failures on shutdown.
reply <- nil
return
} else if err != nil || len(r) == 0 {
fails++ fails++
tab.db.UpdateFindFails(n.ID(), fails) tab.db.UpdateFindFails(n.ID(), fails)
log.Trace("Findnode failed", "id", n.ID(), "failcount", fails, "err", err) log.Trace("Findnode failed", "id", n.ID(), "failcount", fails, "err", err)
@ -329,7 +337,7 @@ func (tab *Table) refresh() <-chan struct{} {
done := make(chan struct{}) done := make(chan struct{})
select { select {
case tab.refreshReq <- done: case tab.refreshReq <- done:
case <-tab.closed: case <-tab.closeReq:
close(done) close(done)
} }
return done return done