Source File
query.go
Belonging Package
github.com/libp2p/go-libp2p/core/routing
package routingimport ()// QueryEventType indicates the query event's type.type QueryEventType int// Number of events to buffer.var QueryEventBufferSize = 16const (// Sending a query to a peer.SendingQuery QueryEventType = iota// Got a response from a peer.PeerResponse// Found a "closest" peer (not currently used).FinalPeer// Got an error when querying.QueryError// Found a provider.Provider// Found a value.Value// Adding a peer to the query.AddingPeer// Dialing a peer.DialingPeer)// QueryEvent is emitted for every notable event that happens during a DHT query.type QueryEvent struct {ID peer.IDType QueryEventTypeResponses []*peer.AddrInfoExtra string}type routingQueryKey struct{}type eventChannel struct {mu sync.Mutexctx context.Contextch chan<- *QueryEvent}// waitThenClose is spawned in a goroutine when the channel is registered. This// safely cleans up the channel when the context has been canceled.func ( *eventChannel) () {<-.ctx.Done().mu.Lock()close(.ch)// 1. Signals that we're done.// 2. Frees memory (in case we end up hanging on to this for a while)..ch = nil.mu.Unlock()}// send sends an event on the event channel, aborting if either the passed or// the internal context expire.func ( *eventChannel) ( context.Context, *QueryEvent) {.mu.Lock()// Closed.if .ch == nil {.mu.Unlock()return}// in case the passed context is unrelated, wait on both.select {case .ch <- :case <-.ctx.Done():case <-.Done():}.mu.Unlock()}// RegisterForQueryEvents registers a query event channel with the given// context. The returned context can be passed to DHT queries to receive query// events on the returned channels.//// The passed context MUST be canceled when the caller is no longer interested// in query events.func ( context.Context) (context.Context, <-chan *QueryEvent) {:= make(chan *QueryEvent, QueryEventBufferSize):= &eventChannel{ch: , ctx: }go .waitThenClose()return context.WithValue(, routingQueryKey{}, ),}// PublishQueryEvent publishes a query event to the query event channel// associated with the given context, if any.func ( context.Context, *QueryEvent) {:= .Value(routingQueryKey{})if == nil {return}// We *want* to panic here.:= .(*eventChannel).send(, )}// SubscribesToQueryEvents returns true if the context subscribes to query// events. If this function returns false, calling `PublishQueryEvent` on the// context will be a no-op.func ( context.Context) bool {return .Value(routingQueryKey{}) != nil}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |