p2p/discutil: add Close to iterator interface

This commit is contained in:
Felix Lange 2019-07-07 23:11:07 +02:00
parent c592367d0b
commit be439f4221
2 changed files with 19 additions and 2 deletions

View file

@ -31,10 +31,13 @@ import (
// node could be found before the context was canceled. The isLive return value reports // node could be found before the context was canceled. The isLive return value reports
// whether the iterator is still open. Once closed, iterators should keep returning (nil, false). // whether the iterator is still open. Once closed, iterators should keep returning (nil, false).
// //
// Implementations are not required to be safe for concurrent use. It is therefore unsafe // Implementations of NextNode are not required to be safe for concurrent use. It is
// to call NextNode from multiple goroutines at the same time. // therefore unsafe to call NextNode from multiple goroutines at the same time.
//
// Close may be called concurrently with NextNode, and interrupts NextNode.
type Iterator interface { type Iterator interface {
NextNode(ctx context.Context) (n *enode.Node, isLive bool) NextNode(ctx context.Context) (n *enode.Node, isLive bool)
Close()
} }
// ReadNodes reads at most n nodes from the given iterator. The return value contains no // ReadNodes reads at most n nodes from the given iterator. The return value contains no
@ -83,6 +86,10 @@ func (f *filterIter) NextNode(ctx context.Context) (*enode.Node, bool) {
return n, isLive return n, isLive
} }
func (f *filterIter) Close() {
f.it.Close()
}
// FairMix aggregates multiple node iterators. The mixer itself is an iterator which ends // FairMix aggregates multiple node iterators. The mixer itself is an iterator which ends
// only when Close is called. Source iterators added via AddSource are removed from the mix // only when Close is called. Source iterators added via AddSource are removed from the mix
// when they end. // when they end.

View file

@ -227,6 +227,8 @@ func (s *genIter) NextNode(ctx context.Context) (*enode.Node, bool) {
return n, true return n, true
} }
func (s *genIter) Close() { panic("called") }
func testNode(id, seq uint64) *enode.Node { func testNode(id, seq uint64) *enode.Node {
var nodeID enode.ID var nodeID enode.ID
binary.BigEndian.PutUint64(nodeID[:], id) binary.BigEndian.PutUint64(nodeID[:], id)
@ -253,6 +255,8 @@ func (s *blockedIter) NextNode(ctx context.Context) (*enode.Node, bool) {
} }
} }
func (s *blockedIter) Close() { panic("called") }
// cycleNodes is a never-ending interator that cycles through the given slice. // cycleNodes is a never-ending interator that cycles through the given slice.
type cycleNodes []*enode.Node type cycleNodes []*enode.Node
@ -267,6 +271,8 @@ func (s cycleNodes) NextNode(ctx context.Context) (*enode.Node, bool) {
return n, true return n, true
} }
func (s cycleNodes) Close() { panic("called") }
// callCountIter counts calls to NextNode. // callCountIter counts calls to NextNode.
type callCountIter struct { type callCountIter struct {
child Iterator child Iterator
@ -277,3 +283,7 @@ func (it *callCountIter) NextNode(ctx context.Context) (*enode.Node, bool) {
it.count++ it.count++
return it.child.NextNode(ctx) return it.child.NextNode(ctx)
} }
func (it *callCountIter) Close() {
it.child.Close()
}