mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-17 02:47:51 +01:00
More changes coming. Rename of organization to Peernet s.r.o. InformationRequest proper termination signal.
70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
/*
|
|
File Name: Information Request.go
|
|
Copyright: 2021 Peernet s.r.o.
|
|
Author: Peter Kleissner
|
|
|
|
Information requests are asynchronous queries sent to nodes.
|
|
*/
|
|
|
|
package dht
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// InformationRequest is an asynchronous request sent. It tracks any asynchronous replies and handles timeouts.
|
|
type InformationRequest struct {
|
|
Action int // IterateFindNode or IterateFindValue
|
|
Key []byte // Target key
|
|
ResultChan chan *NodeMessage // Result channel
|
|
IsTerminated bool // If true, it was signaled for termination
|
|
TerminateSignal chan interface{} // gets closed on termination signal, can be used in select via "case _ = <- network.terminateSignal:"
|
|
sync.Mutex // for sychronized closing
|
|
}
|
|
|
|
// NewInformationRequest creates a new information request
|
|
func NewInformationRequest(Action int, Key []byte) (ir *InformationRequest) {
|
|
return &InformationRequest{
|
|
ResultChan: make(chan *NodeMessage),
|
|
Action: Action,
|
|
Key: Key,
|
|
}
|
|
}
|
|
|
|
// CollectResults collects all information request responses within the given timeout.
|
|
func (ir *InformationRequest) CollectResults(timeout time.Duration) (results []*NodeMessage) {
|
|
for {
|
|
select {
|
|
case result := <-ir.ResultChan:
|
|
results = append(results, result)
|
|
|
|
case <-time.After(timeout):
|
|
ir.Terminate()
|
|
return
|
|
|
|
case <-ir.TerminateSignal:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// Terminate sends the termination signal to all workers. It is safe to call Terminate multiple times.
|
|
func (ir *InformationRequest) Terminate() {
|
|
ir.Lock()
|
|
defer ir.Unlock()
|
|
|
|
if ir.IsTerminated {
|
|
return
|
|
}
|
|
|
|
// set the termination signal
|
|
ir.IsTerminated = true
|
|
close(ir.TerminateSignal) // safety guaranteed via lock
|
|
|
|
close(ir.ResultChan)
|
|
}
|
|
|
|
// TODO: Incoming information request responses should be handled in batches, i.e. every X ms (for example 100ms) without waiting for all results to finish.
|
|
// This could seriously speed up discovery.
|