mirror of
https://github.com/libp2p/go-libp2p-peerstore.git
synced 2025-01-26 04:30:07 +08:00
fix: handle funky clocks when removing expired addresses
When setting the TTL to 0, we expect `UpdateAddrs` to atomically delete the addresses. However, due to funky clock stuff, "now" isn't always consistent and seems to make us think these addresses are _about_ to expire. Funky clock stuff -> `time.Now().Add(0).Unix() > time.Now().Unix()` in some cases...
This commit is contained in:
parent
1907cca69f
commit
810b492220
@ -99,14 +99,16 @@ func (r *addrsRecord) clean() (chgd bool) {
|
||||
return true
|
||||
}
|
||||
|
||||
if r.dirty && addrsLen > 1 {
|
||||
// First remove expired.
|
||||
r.Addrs = removeExpired(r.Addrs, now)
|
||||
|
||||
// Then sort if there's anything to do.
|
||||
if r.dirty && len(r.Addrs) > 0 {
|
||||
sort.Slice(r.Addrs, func(i, j int) bool {
|
||||
return r.Addrs[i].Expiry < r.Addrs[j].Expiry
|
||||
})
|
||||
}
|
||||
|
||||
r.Addrs = removeExpired(r.Addrs, now)
|
||||
|
||||
return r.dirty || len(r.Addrs) != addrsLen
|
||||
}
|
||||
|
||||
@ -118,17 +120,22 @@ func (r *addrsRecord) hasExpiredAddrs(now int64) bool {
|
||||
}
|
||||
|
||||
func removeExpired(entries []*pb.AddrBookRecord_AddrEntry, now int64) []*pb.AddrBookRecord_AddrEntry {
|
||||
// since addresses are sorted by expiration, we find the first
|
||||
// survivor and split the slice on its index.
|
||||
pivot := -1
|
||||
for i, addr := range entries {
|
||||
if addr.Expiry > now {
|
||||
break
|
||||
// Filter out expired addresses in-place.
|
||||
newEntries := entries[:0]
|
||||
for _, addr := range entries {
|
||||
// Sometimes clocks do funy things so we check the TTL as well.
|
||||
if addr.Ttl == 0 || addr.Expiry <= now {
|
||||
continue
|
||||
}
|
||||
pivot = i
|
||||
newEntries = append(newEntries, addr)
|
||||
}
|
||||
|
||||
return entries[pivot+1:]
|
||||
// Let Go's GC free the remaining addresses.
|
||||
for i := len(newEntries); i < len(entries); i++ {
|
||||
entries[i] = nil
|
||||
}
|
||||
|
||||
return newEntries
|
||||
}
|
||||
|
||||
// dsAddrBook is an address book backed by a Datastore with a GC procedure to purge expired entries. It uses an
|
||||
|
Loading…
Reference in New Issue
Block a user