Unverified Commit 35dc0732 authored by Steven Allen's avatar Steven Allen Committed by GitHub

Merge pull request #129 from libp2p/feat/cache-interface-addrs

feat: cache interface addresses for 1 minute
parents 99831444 1b20b7bb
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
goprocessctx "github.com/jbenet/goprocess/context" goprocessctx "github.com/jbenet/goprocess/context"
filter "github.com/libp2p/go-maddr-filter" filter "github.com/libp2p/go-maddr-filter"
ma "github.com/multiformats/go-multiaddr"
mafilter "github.com/whyrusleeping/multiaddr-filter" mafilter "github.com/whyrusleeping/multiaddr-filter"
) )
...@@ -58,6 +59,10 @@ type Swarm struct { ...@@ -58,6 +59,10 @@ type Swarm struct {
listeners struct { listeners struct {
sync.RWMutex sync.RWMutex
ifaceListenAddres []ma.Multiaddr
cacheEOL time.Time
m map[transport.Listener]struct{} m map[transport.Listener]struct{}
} }
......
package swarm package swarm
import ( import (
"time"
addrutil "github.com/libp2p/go-addr-util" addrutil "github.com/libp2p/go-addr-util"
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
) )
...@@ -9,6 +11,10 @@ import ( ...@@ -9,6 +11,10 @@ import (
func (s *Swarm) ListenAddresses() []ma.Multiaddr { func (s *Swarm) ListenAddresses() []ma.Multiaddr {
s.listeners.RLock() s.listeners.RLock()
defer s.listeners.RUnlock() defer s.listeners.RUnlock()
return s.listenAddressesNoLock()
}
func (s *Swarm) listenAddressesNoLock() []ma.Multiaddr {
addrs := make([]ma.Multiaddr, 0, len(s.listeners.m)) addrs := make([]ma.Multiaddr, 0, len(s.listeners.m))
for l := range s.listeners.m { for l := range s.listeners.m {
addrs = append(addrs, l.Multiaddr()) addrs = append(addrs, l.Multiaddr())
...@@ -16,9 +22,47 @@ func (s *Swarm) ListenAddresses() []ma.Multiaddr { ...@@ -16,9 +22,47 @@ func (s *Swarm) ListenAddresses() []ma.Multiaddr {
return addrs return addrs
} }
const ifaceAddrsCacheDuration = 1 * time.Minute
// InterfaceListenAddresses returns a list of addresses at which this swarm // InterfaceListenAddresses returns a list of addresses at which this swarm
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to // listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces. // use the known local interfaces.
func (s *Swarm) InterfaceListenAddresses() ([]ma.Multiaddr, error) { func (s *Swarm) InterfaceListenAddresses() ([]ma.Multiaddr, error) {
return addrutil.ResolveUnspecifiedAddresses(s.ListenAddresses(), nil) s.listeners.RLock() // RLock start
ifaceListenAddres := s.listeners.ifaceListenAddres
isEOL := time.Now().After(s.listeners.cacheEOL)
s.listeners.RUnlock() // RLock end
if ifaceListenAddres != nil && !isEOL {
// Cache is valid
return ifaceListenAddres, nil
}
// Cache is not valid
// Perfrom double checked locking
s.listeners.Lock() // Lock start
ifaceListenAddres = s.listeners.ifaceListenAddres
isEOL = time.Now().After(s.listeners.cacheEOL)
if ifaceListenAddres == nil || isEOL {
// Cache is still invalid
var err error
ifaceListenAddres, err = addrutil.ResolveUnspecifiedAddresses(
s.listenAddressesNoLock(), nil)
if err != nil {
s.listeners.Unlock() // Lock early exit
return nil, err
}
s.listeners.ifaceListenAddres = ifaceListenAddres
s.listeners.cacheEOL = time.Now().Add(ifaceAddrsCacheDuration)
}
s.listeners.Unlock() // Lock end
return ifaceListenAddres, nil
} }
...@@ -2,6 +2,7 @@ package swarm ...@@ -2,6 +2,7 @@ package swarm
import ( import (
"fmt" "fmt"
"time"
"github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/network"
...@@ -55,6 +56,7 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error { ...@@ -55,6 +56,7 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error {
} }
s.refs.Add(1) s.refs.Add(1)
s.listeners.m[list] = struct{}{} s.listeners.m[list] = struct{}{}
s.listeners.cacheEOL = time.Time{}
s.listeners.Unlock() s.listeners.Unlock()
maddr := list.Multiaddr() maddr := list.Multiaddr()
...@@ -69,6 +71,7 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error { ...@@ -69,6 +71,7 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error {
list.Close() list.Close()
s.listeners.Lock() s.listeners.Lock()
delete(s.listeners.m, list) delete(s.listeners.m, list)
s.listeners.cacheEOL = time.Time{}
s.listeners.Unlock() s.listeners.Unlock()
s.refs.Done() s.refs.Done()
}() }()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment