Commit 796e96c9 authored by Steven Allen's avatar Steven Allen

Avoid blocking in notification handlers.

This isn't the correct fix but the correct fix is probably not worth it.

introduces #70
parent 4e8a5204
package dht package dht
import ( import (
"context"
"io" "io"
"time"
inet "github.com/libp2p/go-libp2p-net" inet "github.com/libp2p/go-libp2p-net"
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
mstream "github.com/multiformats/go-multistream" mstream "github.com/multiformats/go-multistream"
) )
// TODO: There is a race condition here where we could process notifications
// out-of-order and incorrectly mark some peers as DHT nodes (or not DHT nodes).
// The correct fix for this is nasty so I'm not really sure it's worth it.
// Incorrectly recording or failing to record a DHT node in the routing table
// isn't a big issue.
const dhtCheckTimeout = 10 * time.Second
// netNotifiee defines methods to be used with the IpfsDHT // netNotifiee defines methods to be used with the IpfsDHT
type netNotifiee IpfsDHT type netNotifiee IpfsDHT
...@@ -23,11 +33,21 @@ func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) { ...@@ -23,11 +33,21 @@ func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) {
default: default:
} }
go func() {
// Note: We *could* just check the peerstore to see if the remote side supports the dht // Note: We *could* just check the peerstore to see if the remote side supports the dht
// protocol, but its not clear that that information will make it into the peerstore // protocol, but its not clear that that information will make it into the peerstore
// by the time this notification is sent. So just to be very careful, we brute force this // by the time this notification is sent. So just to be very careful, we brute force this
// and open a new stream // and open a new stream
s, err := dht.host.NewStream(dht.Context(), v.RemotePeer(), ProtocolDHT, ProtocolDHTOld)
// TODO: There's a race condition here where the connection may
// not be open (and we may sit here trying to connect). I've
// added a timeout but that's not really the correct fix.
ctx, cancel := context.WithTimeout(dht.Context(), dhtCheckTimeout)
defer cancel()
s, err := dht.host.NewStream(ctx, v.RemotePeer(), ProtocolDHT, ProtocolDHTOld)
switch err { switch err {
case nil: case nil:
s.Close() s.Close()
...@@ -42,6 +62,7 @@ func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) { ...@@ -42,6 +62,7 @@ func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) {
// real error? thats odd // real error? thats odd
log.Errorf("checking dht client type: %s", err) log.Errorf("checking dht client type: %s", err)
} }
}()
} }
func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) { func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) {
...@@ -51,7 +72,7 @@ func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) { ...@@ -51,7 +72,7 @@ func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) {
return return
default: default:
} }
dht.routingTable.Remove(v.RemotePeer()) go dht.routingTable.Remove(v.RemotePeer())
} }
func (nn *netNotifiee) OpenedStream(n inet.Network, v inet.Stream) {} func (nn *netNotifiee) OpenedStream(n inet.Network, v inet.Stream) {}
......
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