mirror of
https://github.com/libp2p/go-libp2p-peerstore.git
synced 2025-02-04 06:00:10 +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
|
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 {
|
sort.Slice(r.Addrs, func(i, j int) bool {
|
||||||
return r.Addrs[i].Expiry < r.Addrs[j].Expiry
|
return r.Addrs[i].Expiry < r.Addrs[j].Expiry
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Addrs = removeExpired(r.Addrs, now)
|
|
||||||
|
|
||||||
return r.dirty || len(r.Addrs) != addrsLen
|
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 {
|
func removeExpired(entries []*pb.AddrBookRecord_AddrEntry, now int64) []*pb.AddrBookRecord_AddrEntry {
|
||||||
// since addresses are sorted by expiration, we find the first
|
// Filter out expired addresses in-place.
|
||||||
// survivor and split the slice on its index.
|
newEntries := entries[:0]
|
||||||
pivot := -1
|
for _, addr := range entries {
|
||||||
for i, addr := range entries {
|
// Sometimes clocks do funy things so we check the TTL as well.
|
||||||
if addr.Expiry > now {
|
if addr.Ttl == 0 || addr.Expiry <= now {
|
||||||
break
|
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
|
// 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