refactor-for-testability (#3)
Co-authored-by: jdl <jdl@desktop> Co-authored-by: jdl <jdl@crumpington.com> Reviewed-on: #3
This commit is contained in:
86
peer/pubaddrs.go
Normal file
86
peer/pubaddrs.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package peer
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type pubAddrStore struct {
|
||||
lock sync.Mutex
|
||||
localPub bool
|
||||
localAddr netip.AddrPort
|
||||
lastSeen map[netip.AddrPort]time.Time
|
||||
addrList []netip.AddrPort
|
||||
}
|
||||
|
||||
func newPubAddrStore(localAddr netip.AddrPort) *pubAddrStore {
|
||||
return &pubAddrStore{
|
||||
localPub: localAddr.IsValid(),
|
||||
localAddr: localAddr,
|
||||
lastSeen: map[netip.AddrPort]time.Time{},
|
||||
addrList: make([]netip.AddrPort, 0, 32),
|
||||
}
|
||||
}
|
||||
|
||||
func (store *pubAddrStore) Store(addr netip.AddrPort) {
|
||||
if store.localPub {
|
||||
return
|
||||
}
|
||||
|
||||
if !addr.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
if addr.Addr().IsPrivate() {
|
||||
return
|
||||
}
|
||||
|
||||
store.lock.Lock()
|
||||
defer store.lock.Unlock()
|
||||
|
||||
if _, exists := store.lastSeen[addr]; !exists {
|
||||
store.addrList = append(store.addrList, addr)
|
||||
}
|
||||
store.lastSeen[addr] = time.Now()
|
||||
store.sort()
|
||||
}
|
||||
|
||||
func (store *pubAddrStore) Get() (addrs [8]netip.AddrPort) {
|
||||
store.lock.Lock()
|
||||
defer store.lock.Unlock()
|
||||
|
||||
store.clean()
|
||||
|
||||
if store.localPub {
|
||||
addrs[0] = store.localAddr
|
||||
return
|
||||
}
|
||||
|
||||
copy(addrs[:], store.addrList)
|
||||
return
|
||||
}
|
||||
|
||||
func (store *pubAddrStore) clean() {
|
||||
if store.localPub {
|
||||
return
|
||||
}
|
||||
|
||||
for ip, lastSeen := range store.lastSeen {
|
||||
if time.Since(lastSeen) > timeoutInterval {
|
||||
delete(store.lastSeen, ip)
|
||||
}
|
||||
}
|
||||
store.addrList = store.addrList[:0]
|
||||
for ip := range store.lastSeen {
|
||||
store.addrList = append(store.addrList, ip)
|
||||
}
|
||||
store.sort()
|
||||
}
|
||||
|
||||
func (store *pubAddrStore) sort() {
|
||||
sort.Slice(store.addrList, func(i, j int) bool {
|
||||
return store.lastSeen[store.addrList[j]].Before(store.lastSeen[store.addrList[i]])
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user