Commit 494ade37 authored by Jeromy Johnson's avatar Jeromy Johnson Committed by GitHub
Browse files

Merge pull request #115 from libp2p/feat/improve-mdns

don't block on DiscoverHandler
parents 4d1c7a91 e6a5c5c2
package discovery package discovery
import ( import (
"context"
"errors" "errors"
"io" "io"
"io/ioutil" "io/ioutil"
...@@ -60,7 +61,7 @@ func getDialableListenAddrs(ph host.Host) ([]*net.TCPAddr, error) { ...@@ -60,7 +61,7 @@ func getDialableListenAddrs(ph host.Host) ([]*net.TCPAddr, error) {
return out, nil return out, nil
} }
func NewMdnsService(peerhost host.Host, interval time.Duration) (Service, error) { func NewMdnsService(ctx context.Context, peerhost host.Host, interval time.Duration) (Service, error) {
// TODO: dont let mdns use logging... // TODO: dont let mdns use logging...
golog.SetOutput(ioutil.Discard) golog.SetOutput(ioutil.Discard)
...@@ -99,7 +100,7 @@ func NewMdnsService(peerhost host.Host, interval time.Duration) (Service, error) ...@@ -99,7 +100,7 @@ func NewMdnsService(peerhost host.Host, interval time.Duration) (Service, error)
interval: interval, interval: interval,
} }
go s.pollForEntries() go s.pollForEntries(ctx)
return s, nil return s, nil
} }
...@@ -108,9 +109,12 @@ func (m *mdnsService) Close() error { ...@@ -108,9 +109,12 @@ func (m *mdnsService) Close() error {
return m.server.Shutdown() return m.server.Shutdown()
} }
func (m *mdnsService) pollForEntries() { func (m *mdnsService) pollForEntries(ctx context.Context) {
ticker := time.NewTicker(m.interval) ticker := time.NewTicker(m.interval)
for range ticker.C { for {
select {
case <-ticker.C:
entriesCh := make(chan *mdns.ServiceEntry, 16) entriesCh := make(chan *mdns.ServiceEntry, 16)
go func() { go func() {
for entry := range entriesCh { for entry := range entriesCh {
...@@ -118,21 +122,29 @@ func (m *mdnsService) pollForEntries() { ...@@ -118,21 +122,29 @@ func (m *mdnsService) pollForEntries() {
} }
}() }()
qp := mdns.QueryParam{} log.Debug("starting mdns query")
qp.Domain = "local" qp := &mdns.QueryParam{
qp.Entries = entriesCh Domain: "local",
qp.Service = ServiceTag Entries: entriesCh,
qp.Timeout = time.Second * 5 Service: ServiceTag,
Timeout: time.Second * 5,
}
err := mdns.Query(&qp) err := mdns.Query(qp)
if err != nil { if err != nil {
log.Error("mdns lookup error: ", err) log.Error("mdns lookup error: ", err)
} }
close(entriesCh) close(entriesCh)
log.Debug("mdns query complete")
case <-ctx.Done():
log.Debug("mdns service halting")
return
}
} }
} }
func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) { func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) {
log.Debugf("Handling MDNS entry: %s:%d %s", e.AddrV4, e.Port, e.Info)
mpeer, err := peer.IDB58Decode(e.Info) mpeer, err := peer.IDB58Decode(e.Info)
if err != nil { if err != nil {
log.Warning("Error parsing peer ID from mdns entry: ", err) log.Warning("Error parsing peer ID from mdns entry: ", err)
...@@ -140,6 +152,7 @@ func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) { ...@@ -140,6 +152,7 @@ func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) {
} }
if mpeer == m.host.ID() { if mpeer == m.host.ID() {
log.Debug("got our own mdns entry, skipping")
return return
} }
...@@ -159,7 +172,7 @@ func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) { ...@@ -159,7 +172,7 @@ func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) {
m.lk.Lock() m.lk.Lock()
for _, n := range m.notifees { for _, n := range m.notifees {
n.HandlePeerFound(pi) go n.HandlePeerFound(pi)
} }
m.lk.Unlock() m.lk.Unlock()
} }
......
package discovery
import (
"context"
"testing"
"time"
host "github.com/libp2p/go-libp2p/p2p/host"
netutil "github.com/libp2p/go-libp2p/p2p/test/util"
pstore "github.com/ipfs/go-libp2p-peerstore"
)
type DiscoveryNotifee struct {
h host.Host
}
func (n *DiscoveryNotifee) HandlePeerFound(pi pstore.PeerInfo) {
n.h.Connect(context.Background(), pi)
}
func TestMdnsDiscovery(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
a := netutil.GenHostSwarm(t, ctx)
b := netutil.GenHostSwarm(t, ctx)
sa, err := NewMdnsService(ctx, a, time.Second)
if err != nil {
t.Fatal(err)
}
sb, err := NewMdnsService(ctx, b, time.Second)
if err != nil {
t.Fatal(err)
}
_ = sb
n := &DiscoveryNotifee{a}
sa.RegisterNotifee(n)
time.Sleep(time.Second * 2)
err = a.Connect(ctx, pstore.PeerInfo{ID: b.ID()})
if err != nil {
t.Fatal(err)
}
}
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