mirror of https://github.com/libp2p/go-libp2p.git
Marten Seemann
3 years ago
3 changed files with 124 additions and 0 deletions
@ -0,0 +1,73 @@ |
|||||
|
package blankhost |
||||
|
|
||||
|
import ( |
||||
|
"sync" |
||||
|
|
||||
|
"github.com/libp2p/go-libp2p-core/event" |
||||
|
"github.com/libp2p/go-libp2p-core/network" |
||||
|
"github.com/libp2p/go-libp2p-core/peer" |
||||
|
|
||||
|
ma "github.com/multiformats/go-multiaddr" |
||||
|
) |
||||
|
|
||||
|
type peerConnectWatcher struct { |
||||
|
emitter event.Emitter |
||||
|
|
||||
|
mutex sync.Mutex |
||||
|
connected map[peer.ID]struct{} |
||||
|
} |
||||
|
|
||||
|
var _ network.Notifiee = &peerConnectWatcher{} |
||||
|
|
||||
|
func newPeerConnectWatcher(emitter event.Emitter) *peerConnectWatcher { |
||||
|
return &peerConnectWatcher{ |
||||
|
emitter: emitter, |
||||
|
connected: make(map[peer.ID]struct{}), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (w *peerConnectWatcher) Listen(network.Network, ma.Multiaddr) {} |
||||
|
func (w *peerConnectWatcher) ListenClose(network.Network, ma.Multiaddr) {} |
||||
|
func (w *peerConnectWatcher) OpenedStream(network.Network, network.Stream) {} |
||||
|
func (w *peerConnectWatcher) ClosedStream(network.Network, network.Stream) {} |
||||
|
|
||||
|
func (w *peerConnectWatcher) Connected(n network.Network, conn network.Conn) { |
||||
|
p := conn.RemotePeer() |
||||
|
w.handleTransition(p, n.Connectedness(p)) |
||||
|
} |
||||
|
|
||||
|
func (w *peerConnectWatcher) Disconnected(n network.Network, conn network.Conn) { |
||||
|
p := conn.RemotePeer() |
||||
|
w.handleTransition(p, n.Connectedness(p)) |
||||
|
} |
||||
|
|
||||
|
func (w *peerConnectWatcher) handleTransition(p peer.ID, state network.Connectedness) { |
||||
|
if changed := w.checkTransition(p, state); !changed { |
||||
|
return |
||||
|
} |
||||
|
w.emitter.Emit(event.EvtPeerConnectednessChanged{ |
||||
|
Peer: p, |
||||
|
Connectedness: state, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
func (w *peerConnectWatcher) checkTransition(p peer.ID, state network.Connectedness) bool { |
||||
|
w.mutex.Lock() |
||||
|
defer w.mutex.Unlock() |
||||
|
switch state { |
||||
|
case network.Connected: |
||||
|
if _, ok := w.connected[p]; ok { |
||||
|
return false |
||||
|
} |
||||
|
w.connected[p] = struct{}{} |
||||
|
return true |
||||
|
case network.NotConnected: |
||||
|
if _, ok := w.connected[p]; ok { |
||||
|
delete(w.connected, p) |
||||
|
return true |
||||
|
} |
||||
|
return false |
||||
|
default: |
||||
|
return false |
||||
|
} |
||||
|
} |
@ -0,0 +1,46 @@ |
|||||
|
package blankhost |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/libp2p/go-libp2p-core/event" |
||||
|
"github.com/libp2p/go-libp2p-core/network" |
||||
|
"github.com/libp2p/go-libp2p-core/peer" |
||||
|
swarmt "github.com/libp2p/go-libp2p-swarm/testing" |
||||
|
|
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
func TestPeerConnectedness(t *testing.T) { |
||||
|
h1 := NewBlankHost(swarmt.GenSwarm(t)) |
||||
|
defer h1.Close() |
||||
|
h2 := NewBlankHost(swarmt.GenSwarm(t)) |
||||
|
|
||||
|
sub1, err := h1.EventBus().Subscribe(&event.EvtPeerConnectednessChanged{}) |
||||
|
require.NoError(t, err) |
||||
|
defer sub1.Close() |
||||
|
sub2, err := h2.EventBus().Subscribe(&event.EvtPeerConnectednessChanged{}) |
||||
|
require.NoError(t, err) |
||||
|
defer sub2.Close() |
||||
|
|
||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
||||
|
defer cancel() |
||||
|
require.NoError(t, h1.Connect(ctx, peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})) |
||||
|
require.Equal(t, (<-sub1.Out()).(event.EvtPeerConnectednessChanged), event.EvtPeerConnectednessChanged{ |
||||
|
Peer: h2.ID(), |
||||
|
Connectedness: network.Connected, |
||||
|
}) |
||||
|
require.Equal(t, (<-sub2.Out()).(event.EvtPeerConnectednessChanged), event.EvtPeerConnectednessChanged{ |
||||
|
Peer: h1.ID(), |
||||
|
Connectedness: network.Connected, |
||||
|
}) |
||||
|
|
||||
|
// now close h2. This will disconnect it from h1.
|
||||
|
require.NoError(t, h2.Close()) |
||||
|
require.Equal(t, (<-sub1.Out()).(event.EvtPeerConnectednessChanged), event.EvtPeerConnectednessChanged{ |
||||
|
Peer: h2.ID(), |
||||
|
Connectedness: network.NotConnected, |
||||
|
}) |
||||
|
} |
Loading…
Reference in new issue