github.com/metacurrency/holochain@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/notifi.go (about)

     1  // Copyright (C) 2013-2017, The MetaCurrency Project (Eric Harris-Braun, Arthur Brock, et. al.)
     2  // Use of this source code is governed by GPLv3 found in the LICENSE file
     3  //----------------------------------------------------------------------------------------
     4  //
     5  // This code is adapted from the libp2p project, specifically:
     6  // https://github.com/libp2p/go-libp2p-kad-dht/notif.go
     7  //
     8  // The ipfs use of kademlia is substantially different than that needed by holochain so we remove
     9  // parts we don't need and add others.
    10  //
    11  package holochain
    12  
    13  import (
    14  	"context"
    15  	inet "github.com/libp2p/go-libp2p-net"
    16  	ma "github.com/multiformats/go-multiaddr"
    17  )
    18  
    19  // netNotifiee defines methods to be used with the Holochain Node
    20  type netNotifiee Node
    21  
    22  func (nn *netNotifiee) Node() *Node {
    23  	return (*Node)(nn)
    24  }
    25  
    26  type peerTracker struct {
    27  	refcount int
    28  	cancel   func()
    29  }
    30  
    31  func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) {
    32  	node := nn.Node()
    33  	select {
    34  	case <-node.Process().Closing():
    35  		return
    36  	default:
    37  	}
    38  
    39  	node.plk.Lock()
    40  	defer node.plk.Unlock()
    41  
    42  	conn, ok := nn.peers[v.RemotePeer()]
    43  	if ok {
    44  		conn.refcount++
    45  		return
    46  	}
    47  
    48  	ctx, cancel := context.WithCancel(node.Context())
    49  
    50  	nn.peers[v.RemotePeer()] = &peerTracker{
    51  		refcount: 1,
    52  		cancel:   cancel,
    53  	}
    54  
    55  	// Check if canceled under the lock.
    56  	if ctx.Err() == nil {
    57  		node.routingTable.Update(v.RemotePeer())
    58  	}
    59  }
    60  
    61  func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) {
    62  	node := nn.Node()
    63  	select {
    64  	case <-node.Process().Closing():
    65  		return
    66  	default:
    67  	}
    68  
    69  	node.plk.Lock()
    70  	defer node.plk.Unlock()
    71  
    72  	conn, ok := nn.peers[v.RemotePeer()]
    73  	if !ok {
    74  		// Unmatched disconnects are fine. It just means that we were
    75  		// already connected when we registered the listener.
    76  		return
    77  	}
    78  	conn.refcount -= 1
    79  	if conn.refcount == 0 {
    80  		delete(nn.peers, v.RemotePeer())
    81  		conn.cancel()
    82  		node.routingTable.Remove(v.RemotePeer())
    83  	}
    84  }
    85  
    86  func (nn *netNotifiee) OpenedStream(n inet.Network, v inet.Stream) {}
    87  func (nn *netNotifiee) ClosedStream(n inet.Network, v inet.Stream) {}
    88  func (nn *netNotifiee) Listen(n inet.Network, a ma.Multiaddr)      {}
    89  func (nn *netNotifiee) ListenClose(n inet.Network, a ma.Multiaddr) {}