mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
dashboard, p2p: different handling of the peers that disconnect before handshake
This commit is contained in:
parent
80135738a6
commit
f2e52e2fee
4 changed files with 193 additions and 166 deletions
|
|
@ -83,8 +83,9 @@ func (m *NetworkMessage) getOrInitPeer(ip, id string) *Peer {
|
||||||
|
|
||||||
// PeerBundle contains information about the peers pertaining to an IP address.
|
// PeerBundle contains information about the peers pertaining to an IP address.
|
||||||
type PeerBundle struct {
|
type PeerBundle struct {
|
||||||
Location *GeoLocation `json:"location,omitempty"` // geographical information based on IP
|
Location *GeoLocation `json:"location,omitempty"` // geographical information based on IP
|
||||||
Peers map[string]*Peer `json:"peers,omitempty"` // the peers' node id is used as key
|
Peers map[string]*Peer `json:"peers,omitempty"` // the peers' node id is used as key
|
||||||
|
FailedPeers []*Peer `json:"failedPeers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeoLocation contains geographical information.
|
// GeoLocation contains geographical information.
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
package dashboard
|
package dashboard
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
|
@ -24,7 +26,8 @@ import (
|
||||||
"github.com/mohae/deepcopy"
|
"github.com/mohae/deepcopy"
|
||||||
)
|
)
|
||||||
|
|
||||||
const eventBufferLimit = 128 // Maximum number of buffered peer events for each event type
|
const eventBufferLimit = 128 // Maximum number of buffered peer events
|
||||||
|
const trafficEventBufferLimit = p2p.MeteredPeerLimit
|
||||||
|
|
||||||
// collectPeerData gathers data about the peers and sends it to the clients.
|
// collectPeerData gathers data about the peers and sends it to the clients.
|
||||||
func (db *Dashboard) collectPeerData() {
|
func (db *Dashboard) collectPeerData() {
|
||||||
|
|
@ -42,29 +45,27 @@ func (db *Dashboard) collectPeerData() {
|
||||||
var (
|
var (
|
||||||
// Peer event channels.
|
// Peer event channels.
|
||||||
connectCh = make(chan p2p.PeerConnectEvent, eventBufferLimit)
|
connectCh = make(chan p2p.PeerConnectEvent, eventBufferLimit)
|
||||||
handshakeCh = make(chan p2p.PeerHandshakeEvent, eventBufferLimit)
|
failedCh = make(chan p2p.PeerFailedEvent, eventBufferLimit)
|
||||||
disconnectCh = make(chan p2p.PeerDisconnectEvent, eventBufferLimit)
|
disconnectCh = make(chan p2p.PeerDisconnectEvent, eventBufferLimit)
|
||||||
//readCh = make(chan p2p.PeerReadEvent, eventBufferLimit)
|
ingressCh = make(chan p2p.PeerTrafficEvent, trafficEventBufferLimit)
|
||||||
//writeCh = make(chan p2p.PeerWriteEvent, eventBufferLimit)
|
egressCh = make(chan p2p.PeerTrafficEvent, trafficEventBufferLimit)
|
||||||
|
|
||||||
// Subscribe to peer events.
|
// Subscribe to peer events.
|
||||||
subConnect = p2p.SubscribePeerConnectEvent(connectCh)
|
subConnect = p2p.SubscribePeerConnectEvent(connectCh)
|
||||||
subHandshake = p2p.SubscribePeerHandshakeEvent(handshakeCh)
|
subFailed = p2p.SubscribePeerFailedEvent(failedCh)
|
||||||
subDisconnect = p2p.SubscribePeerDisconnectEvent(disconnectCh)
|
subDisconnect = p2p.SubscribePeerDisconnectEvent(disconnectCh)
|
||||||
//subRead = p2p.SubscribePeerReadEvent(readCh)
|
subIngress = p2p.SubscribePeerIngressEvent(ingressCh)
|
||||||
//subWrite = p2p.SubscribePeerWriteEvent(writeCh)
|
subEgress = p2p.SubscribePeerEgressEvent(egressCh)
|
||||||
)
|
)
|
||||||
defer func() {
|
defer func() {
|
||||||
// Unsubscribe at the end.
|
// Unsubscribe at the end.
|
||||||
subConnect.Unsubscribe()
|
subConnect.Unsubscribe()
|
||||||
subHandshake.Unsubscribe()
|
subFailed.Unsubscribe()
|
||||||
subDisconnect.Unsubscribe()
|
subDisconnect.Unsubscribe()
|
||||||
//subRead.Unsubscribe()
|
subIngress.Unsubscribe()
|
||||||
//subWrite.Unsubscribe()
|
subEgress.Unsubscribe()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
//go db.keepPeerHistoryClean(quit)
|
|
||||||
|
|
||||||
ticker := time.NewTicker(db.config.Refresh)
|
ticker := time.NewTicker(db.config.Refresh)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
|
@ -74,30 +75,30 @@ func (db *Dashboard) collectPeerData() {
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
//case event := <-connectCh:
|
case event := <-connectCh:
|
||||||
// ip := event.IP.String()
|
ip := event.IP
|
||||||
// p := diff.getOrInitPeer(ip, event.ID)
|
p := diff.getOrInitPeer(ip, event.ID)
|
||||||
// if diff.PeerBundles[ip].Location == nil {
|
if diff.PeerBundles[ip].Location == nil {
|
||||||
// db.peerLock.RLock()
|
db.peerLock.RLock()
|
||||||
// lookup := db.history.Network.PeerBundles[ip] == nil || db.history.Network.PeerBundles[ip].Location == nil
|
lookup := db.history.Network.PeerBundles[ip] == nil || db.history.Network.PeerBundles[ip].Location == nil
|
||||||
// db.peerLock.RUnlock()
|
db.peerLock.RUnlock()
|
||||||
// if lookup {
|
if lookup {
|
||||||
// location := db.geodb.Lookup(event.IP)
|
location := db.geodb.Lookup(net.ParseIP(event.IP))
|
||||||
// diff.PeerBundles[ip].Location = &GeoLocation{
|
diff.PeerBundles[ip].Location = &GeoLocation{
|
||||||
// Country: location.Country.Names.English,
|
Country: location.Country.Names.English,
|
||||||
// City: location.City.Names.English,
|
City: location.City.Names.English,
|
||||||
// Latitude: location.Location.Latitude,
|
Latitude: location.Location.Latitude,
|
||||||
// Longitude: location.Location.Longitude,
|
Longitude: location.Location.Longitude,
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// if p.Connected == nil {
|
if p.Connected == nil {
|
||||||
// p.Connected = []time.Time{event.Connected}
|
p.Connected = []time.Time{event.Connected}
|
||||||
// } else {
|
} else {
|
||||||
// p.Connected = append(p.Connected, event.Connected)
|
p.Connected = append(p.Connected, event.Connected)
|
||||||
// }
|
}
|
||||||
//case event := <-handshakeCh:
|
//case event := <-failedCh:
|
||||||
// ip := event.IP.String()
|
// ip := event.IP
|
||||||
// p := diff.getOrInitPeer(ip, event.AutoID)
|
// p := diff.getOrInitPeer(ip, event.AutoID)
|
||||||
// p.DefaultID = event.AutoID
|
// p.DefaultID = event.AutoID
|
||||||
// if p.Handshake == nil {
|
// if p.Handshake == nil {
|
||||||
|
|
@ -120,29 +121,31 @@ func (db *Dashboard) collectPeerData() {
|
||||||
// db.history.Network.PeerBundles[ip].Peers[event.ID] = hp // TODO (kurkomisi): Merge.
|
// db.history.Network.PeerBundles[ip].Peers[event.ID] = hp // TODO (kurkomisi): Merge.
|
||||||
// db.peerLock.Unlock()
|
// db.peerLock.Unlock()
|
||||||
// }
|
// }
|
||||||
//case event := <-disconnectCh:
|
case event := <-disconnectCh:
|
||||||
// p := diff.getOrInitPeer(event.IP.String(), event.ID)
|
p := diff.getOrInitPeer(event.IP, event.ID)
|
||||||
// if p.Disconnected == nil {
|
if p.Disconnected == nil {
|
||||||
// p.Disconnected = []time.Time{event.Disconnected}
|
p.Disconnected = []time.Time{event.Disconnected}
|
||||||
// } else {
|
} else {
|
||||||
// p.Disconnected = append(p.Disconnected, event.Disconnected)
|
p.Disconnected = append(p.Disconnected, event.Disconnected)
|
||||||
// }
|
}
|
||||||
//case event := <-readCh:
|
case event := <-ingressCh:
|
||||||
// // Sum up the ingress between two updates.
|
fmt.Println("ingress", event.IP, event.Amount)
|
||||||
// p := diff.getOrInitPeer(event.IP.String(), event.ID)
|
// Sum up the ingress between two updates.
|
||||||
// if len(p.Ingress) <= 0 {
|
p := diff.getOrInitPeer(event.IP, event.ID)
|
||||||
// p.Ingress = ChartEntries{&ChartEntry{Value: float64(event.Ingress)}}
|
if len(p.Ingress) <= 0 {
|
||||||
// } else {
|
p.Ingress = ChartEntries{&ChartEntry{Value: float64(event.Amount)}}
|
||||||
// p.Ingress[0].Value += float64(event.Ingress)
|
} else {
|
||||||
// }
|
p.Ingress[0].Value += float64(event.Amount)
|
||||||
//case event := <-writeCh:
|
}
|
||||||
// // Sum up the egress between two updates.
|
case event := <-egressCh:
|
||||||
// p := diff.getOrInitPeer(event.IP.String(), event.ID)
|
fmt.Println("egress ", event.IP, event.Amount)
|
||||||
// if len(p.Egress) <= 0 {
|
// Sum up the egress between two updates.
|
||||||
// p.Egress = ChartEntries{&ChartEntry{Value: float64(event.Egress)}}
|
p := diff.getOrInitPeer(event.IP, event.ID)
|
||||||
// } else {
|
if len(p.Egress) <= 0 {
|
||||||
// p.Egress[0].Value += float64(event.Egress)
|
p.Egress = ChartEntries{&ChartEntry{Value: float64(event.Amount)}}
|
||||||
// }
|
} else {
|
||||||
|
p.Egress[0].Value += float64(event.Amount)
|
||||||
|
}
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
// Merge the diff with the history.
|
// Merge the diff with the history.
|
||||||
|
|
@ -206,18 +209,18 @@ func (db *Dashboard) collectPeerData() {
|
||||||
case err := <-subConnect.Err():
|
case err := <-subConnect.Err():
|
||||||
log.Warn("Peer connect subscription error", "err", err)
|
log.Warn("Peer connect subscription error", "err", err)
|
||||||
return
|
return
|
||||||
case err := <-subHandshake.Err():
|
case err := <-subFailed.Err():
|
||||||
log.Warn("Peer handshake subscription error", "err", err)
|
log.Warn("Peer failed subscription error", "err", err)
|
||||||
return
|
return
|
||||||
case err := <-subDisconnect.Err():
|
case err := <-subDisconnect.Err():
|
||||||
log.Warn("Peer disconnect subscription error", "err", err)
|
log.Warn("Peer disconnect subscription error", "err", err)
|
||||||
return
|
return
|
||||||
//case err := <-subRead.Err():
|
case err := <-subIngress.Err():
|
||||||
// log.Warn("Peer read subscription error", "err", err)
|
log.Warn("Peer ingress subscription error", "err", err)
|
||||||
// return
|
return
|
||||||
//case err := <-subWrite.Err():
|
case err := <-subEgress.Err():
|
||||||
// log.Warn("Peer write subscription error", "err", err)
|
log.Warn("Peer egress subscription error", "err", err)
|
||||||
// return
|
return
|
||||||
case errc := <-db.quit:
|
case errc := <-db.quit:
|
||||||
errc <- nil
|
errc <- nil
|
||||||
return
|
return
|
||||||
|
|
|
||||||
215
p2p/metrics.go
215
p2p/metrics.go
|
|
@ -56,17 +56,16 @@ var (
|
||||||
|
|
||||||
metricsFeed = new(peerMetricsFeed) // Peer event feed for metrics
|
metricsFeed = new(peerMetricsFeed) // Peer event feed for metrics
|
||||||
|
|
||||||
meteredPeerAutoID uint64 // Used to create unique id for the metered connection before the handshake
|
meteredPeerCount uint64
|
||||||
meteredPeerCount uint64
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// peerMetricsFeed delivers the peer metrics to the subscribed channels.
|
// peerMetricsFeed delivers the peer metrics to the subscribed channels.
|
||||||
type peerMetricsFeed struct {
|
type peerMetricsFeed struct {
|
||||||
connect event.Feed // Event feed to notify the connection of a peer
|
connect event.Feed // Event feed to notify the connection and the successful handshake of a peer
|
||||||
handshake event.Feed // Event feed to notify the handshake with a peer
|
ingress event.Feed // Event feed to notify the amount of read bytes of a peer
|
||||||
|
egress event.Feed // Event feed to notify the amount of written bytes of a peer
|
||||||
disconnect event.Feed // Event feed to notify the disconnection of a peer
|
disconnect event.Feed // Event feed to notify the disconnection of a peer
|
||||||
read event.Feed // Event feed to notify the amount of read bytes of a peer
|
failed event.Feed // Event feed to notify the connection of a peer and its disconnection before the handshake
|
||||||
write event.Feed // Event feed to notify the amount of written bytes of a peer
|
|
||||||
|
|
||||||
scope event.SubscriptionScope // Facility to unsubscribe all the subscriptions at once
|
scope event.SubscriptionScope // Facility to unsubscribe all the subscriptions at once
|
||||||
|
|
||||||
|
|
@ -75,79 +74,86 @@ type peerMetricsFeed struct {
|
||||||
|
|
||||||
// PeerConnectEvent contains information about the connection of a peer.
|
// PeerConnectEvent contains information about the connection of a peer.
|
||||||
type PeerConnectEvent struct {
|
type PeerConnectEvent struct {
|
||||||
Key string
|
IP string
|
||||||
|
ID string
|
||||||
Connected time.Time
|
Connected time.Time
|
||||||
}
|
|
||||||
|
|
||||||
// PeerHandshakeEvent contains information about the handshake with a peer.
|
|
||||||
type PeerHandshakeEvent struct {
|
|
||||||
AutoKey string
|
|
||||||
Key string
|
|
||||||
Ingress int64
|
|
||||||
Egress int64
|
|
||||||
Handshake time.Time
|
Handshake time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeerDisconnectEvent contains information about the disconnection of a peer.
|
// PeerDisconnectEvent contains information about the disconnection of a peer.
|
||||||
type PeerDisconnectEvent struct {
|
type PeerDisconnectEvent struct {
|
||||||
Key string
|
IP string
|
||||||
Ingress int64
|
ID string
|
||||||
Egress int64
|
|
||||||
Disconnected time.Time
|
Disconnected time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeerReadEvent contains information about the read operation of a peer.
|
type PeerTrafficEvent struct {
|
||||||
type PeerTrafficEvent map[string]int64
|
IP string
|
||||||
|
ID string
|
||||||
|
Amount int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type PeerFailedEvent struct {
|
||||||
|
IP string
|
||||||
|
Connected time.Time
|
||||||
|
Disconnected time.Time
|
||||||
|
}
|
||||||
|
|
||||||
// SubscribePeerConnectEvent registers a subscription of PeerConnectEvent
|
// SubscribePeerConnectEvent registers a subscription of PeerConnectEvent
|
||||||
func SubscribePeerConnectEvent(ch chan<- PeerConnectEvent) event.Subscription {
|
func SubscribePeerConnectEvent(ch chan<- PeerConnectEvent) event.Subscription {
|
||||||
return metricsFeed.scope.Track(metricsFeed.connect.Subscribe(ch))
|
return metricsFeed.scope.Track(metricsFeed.connect.Subscribe(ch))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribePeerHandshakeEvent registers a subscription of PeerHandshakeEvent
|
|
||||||
func SubscribePeerHandshakeEvent(ch chan<- PeerHandshakeEvent) event.Subscription {
|
|
||||||
return metricsFeed.scope.Track(metricsFeed.handshake.Subscribe(ch))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SubscribePeerDisconnectEvent registers a subscription of PeerDisconnectEvent
|
// SubscribePeerDisconnectEvent registers a subscription of PeerDisconnectEvent
|
||||||
func SubscribePeerDisconnectEvent(ch chan<- PeerDisconnectEvent) event.Subscription {
|
func SubscribePeerDisconnectEvent(ch chan<- PeerDisconnectEvent) event.Subscription {
|
||||||
return metricsFeed.scope.Track(metricsFeed.disconnect.Subscribe(ch))
|
return metricsFeed.scope.Track(metricsFeed.disconnect.Subscribe(ch))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribePeerReadEvent registers a subscription of PeerReadEvent
|
// SubscribePeerTrafficEvent registers a subscription of PeerTrafficEvent
|
||||||
func SubscribePeerReadEvent(ch chan<- PeerTrafficEvent) event.Subscription {
|
|
||||||
return metricsFeed.scope.Track(metricsFeed.read.Subscribe(ch))
|
func SubscribePeerIngressEvent(ch chan<- PeerTrafficEvent) event.Subscription {
|
||||||
|
return metricsFeed.scope.Track(metricsFeed.ingress.Subscribe(ch))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribePeerWriteEvent registers a subscription of PeerWriteEvent
|
func SubscribePeerEgressEvent(ch chan<- PeerTrafficEvent) event.Subscription {
|
||||||
func SubscribePeerWriteEvent(ch chan<- PeerTrafficEvent) event.Subscription {
|
return metricsFeed.scope.Track(metricsFeed.egress.Subscribe(ch))
|
||||||
return metricsFeed.scope.Track(metricsFeed.write.Subscribe(ch))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func startTrafficNotifier(refresh time.Duration) {
|
// SubscribePeerFailedEvent registers a subscription of PeerFailedEvent
|
||||||
|
func SubscribePeerFailedEvent(ch chan<- PeerFailedEvent) event.Subscription {
|
||||||
|
return metricsFeed.scope.Track(metricsFeed.failed.Subscribe(ch))
|
||||||
|
}
|
||||||
|
|
||||||
|
func runMetricsFeedHelper(refresh time.Duration) {
|
||||||
metricsFeed.quit = make(chan chan error)
|
metricsFeed.quit = make(chan chan error)
|
||||||
ticker := time.NewTicker(refresh)
|
ticker := time.NewTicker(refresh)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
// It is possible to send all of the traffic events together, but it is risky to use pointers in the events.
|
||||||
|
trafficEventSender := func(prefix string, feed *event.Feed) func(name string, i interface{}) {
|
||||||
|
return func(name string, i interface{}) {
|
||||||
|
if m, ok := i.(metrics.Meter); ok {
|
||||||
|
// Trim the common prefix and split the peer specific part in order to get the ip and the node id.
|
||||||
|
if key := strings.Split(strings.TrimPrefix(name, prefix), "/"); len(key) == 2 {
|
||||||
|
feed.Send(PeerTrafficEvent{
|
||||||
|
IP: key[0],
|
||||||
|
ID: key[1],
|
||||||
|
Amount: m.Count(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log.Warn("Invalid peer metrics name", "name", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendIngress := trafficEventSender(MetricsRegistryIngressPrefix, &metricsFeed.ingress)
|
||||||
|
sendEgress := trafficEventSender(MetricsRegistryEgressPrefix, &metricsFeed.egress)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
// send read and write
|
PeerIngressRegistry.Each(sendIngress)
|
||||||
ingressEvents, egressEvents := make(PeerTrafficEvent), make(PeerTrafficEvent)
|
PeerEgressRegistry.Each(sendEgress)
|
||||||
PeerIngressRegistry.Each(func(name string, i interface{}) {
|
|
||||||
if m, ok := i.(metrics.Meter); ok {
|
|
||||||
ingressEvents[strings.TrimPrefix(name, MetricsRegistryIngressPrefix)] = m.Count()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
PeerEgressRegistry.Each(func(name string, i interface{}) {
|
|
||||||
if m, ok := i.(metrics.Meter); ok {
|
|
||||||
egressEvents[strings.TrimPrefix(name, MetricsRegistryEgressPrefix)] = m.Count()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
metricsFeed.read.Send(ingressEvents)
|
|
||||||
metricsFeed.write.Send(egressEvents)
|
|
||||||
//fmt.Println(ingressEvents)
|
|
||||||
//fmt.Println(egressEvents)
|
|
||||||
//fmt.Println()
|
|
||||||
case errc := <-metricsFeed.quit:
|
case errc := <-metricsFeed.quit:
|
||||||
errc <- nil
|
errc <- nil
|
||||||
return
|
return
|
||||||
|
|
@ -170,10 +176,11 @@ func closeMetricsFeed() {
|
||||||
// meteredConn is a wrapper around a net.Conn that meters both the
|
// meteredConn is a wrapper around a net.Conn that meters both the
|
||||||
// inbound and outbound network traffic.
|
// inbound and outbound network traffic.
|
||||||
type meteredConn struct {
|
type meteredConn struct {
|
||||||
net.Conn // Network connection to wrap with metering
|
net.Conn // Network connection to wrap with metering
|
||||||
ip string // The IP address of the peer
|
|
||||||
|
|
||||||
key string
|
connected time.Time
|
||||||
|
ip string // The IP address of the peer
|
||||||
|
id string // The NodeID of the peer
|
||||||
ingressMeter metrics.Meter
|
ingressMeter metrics.Meter
|
||||||
egressMeter metrics.Meter
|
egressMeter metrics.Meter
|
||||||
|
|
||||||
|
|
@ -196,24 +203,18 @@ func newMeteredConn(conn net.Conn, ingress bool, ip net.IP) net.Conn {
|
||||||
log.Warn("Metered peer count reached the limit")
|
log.Warn("Metered peer count reached the limit")
|
||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
|
// Increment the metered peer count
|
||||||
atomic.AddUint64(&meteredPeerCount, 1)
|
atomic.AddUint64(&meteredPeerCount, 1)
|
||||||
// Otherwise bump the connection counters and wrap the connection
|
// Bump the connection counters and wrap the connection
|
||||||
if ingress {
|
if ingress {
|
||||||
ingressConnectMeter.Mark(1)
|
ingressConnectMeter.Mark(1)
|
||||||
} else {
|
} else {
|
||||||
egressConnectMeter.Mark(1)
|
egressConnectMeter.Mark(1)
|
||||||
}
|
}
|
||||||
key := fmt.Sprintf("%s/%s", ip.String(), fmt.Sprintf("peer_%d", atomic.AddUint64(&meteredPeerAutoID, 1)))
|
|
||||||
metricsFeed.connect.Send(PeerConnectEvent{
|
|
||||||
Key: key,
|
|
||||||
Connected: time.Now(),
|
|
||||||
})
|
|
||||||
return &meteredConn{
|
return &meteredConn{
|
||||||
Conn: conn,
|
Conn: conn,
|
||||||
key: key,
|
ip: ip.String(),
|
||||||
ip: ip.String(),
|
connected: time.Now(),
|
||||||
ingressMeter: metrics.NewRegisteredMeter(key, PeerIngressRegistry),
|
|
||||||
egressMeter: metrics.NewRegisteredMeter(key, PeerEgressRegistry),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,7 +223,11 @@ func newMeteredConn(conn net.Conn, ingress bool, ip net.IP) net.Conn {
|
||||||
func (c *meteredConn) Read(b []byte) (n int, err error) {
|
func (c *meteredConn) Read(b []byte) (n int, err error) {
|
||||||
n, err = c.Conn.Read(b)
|
n, err = c.Conn.Read(b)
|
||||||
ingressTrafficMeter.Mark(int64(n))
|
ingressTrafficMeter.Mark(int64(n))
|
||||||
c.ingressMeter.Mark(int64(n))
|
c.lock.RLock()
|
||||||
|
if c.ingressMeter != nil {
|
||||||
|
c.ingressMeter.Mark(int64(n))
|
||||||
|
}
|
||||||
|
c.lock.RUnlock()
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,55 +236,73 @@ func (c *meteredConn) Read(b []byte) (n int, err error) {
|
||||||
func (c *meteredConn) Write(b []byte) (n int, err error) {
|
func (c *meteredConn) Write(b []byte) (n int, err error) {
|
||||||
n, err = c.Conn.Write(b)
|
n, err = c.Conn.Write(b)
|
||||||
egressTrafficMeter.Mark(int64(n))
|
egressTrafficMeter.Mark(int64(n))
|
||||||
c.egressMeter.Mark(int64(n))
|
c.lock.RLock()
|
||||||
|
if c.egressMeter != nil {
|
||||||
|
c.egressMeter.Mark(int64(n))
|
||||||
|
}
|
||||||
|
c.lock.RUnlock()
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the underlying connection.
|
// Close closes the underlying connection.
|
||||||
func (c *meteredConn) Close() error {
|
func (c *meteredConn) Close() error {
|
||||||
// Decrement the metered peer count.
|
// Decrement the metered peer count
|
||||||
atomic.AddUint64(&meteredPeerCount, ^uint64(0))
|
atomic.AddUint64(&meteredPeerCount, ^uint64(0))
|
||||||
c.ingressMeter.Stop()
|
err, now := c.Conn.Close(), time.Now()
|
||||||
c.egressMeter.Stop()
|
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
key := c.key
|
ip, id := c.ip, c.id
|
||||||
metricsFeed.disconnect.Send(PeerDisconnectEvent{
|
|
||||||
Key: key,
|
|
||||||
Ingress: c.ingressMeter.Count(),
|
|
||||||
Egress: c.egressMeter.Count(),
|
|
||||||
Disconnected: time.Now(),
|
|
||||||
})
|
|
||||||
c.lock.RUnlock()
|
c.lock.RUnlock()
|
||||||
|
|
||||||
|
// If the peer disconnects before the handshake
|
||||||
|
if id == "" {
|
||||||
|
metricsFeed.failed.Send(PeerFailedEvent{
|
||||||
|
IP: ip,
|
||||||
|
Connected: c.connected,
|
||||||
|
Disconnected: now,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.lock.RLock()
|
||||||
|
//ingress, egress := c.ingressMeter.Count(), c.egressMeter.Count()
|
||||||
|
c.lock.RUnlock()
|
||||||
|
|
||||||
|
// Unregister the peer from the metrics registry
|
||||||
|
key := fmt.Sprintf("%s/%s", ip, id)
|
||||||
PeerIngressRegistry.Unregister(key)
|
PeerIngressRegistry.Unregister(key)
|
||||||
PeerEgressRegistry.Unregister(key)
|
PeerEgressRegistry.Unregister(key)
|
||||||
return c.Conn.Close()
|
|
||||||
|
//metricsFeed.ingress.Send(PeerTrafficEvent{
|
||||||
|
// IP: ip,
|
||||||
|
// ID: id,
|
||||||
|
// Amount: ingress,
|
||||||
|
//})
|
||||||
|
//metricsFeed.egress.Send(PeerTrafficEvent{
|
||||||
|
// IP: ip,
|
||||||
|
// ID: id,
|
||||||
|
// Amount: egress,
|
||||||
|
//})
|
||||||
|
metricsFeed.disconnect.Send(PeerDisconnectEvent{
|
||||||
|
IP: ip,
|
||||||
|
ID: id,
|
||||||
|
Disconnected: now,
|
||||||
|
})
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// handshakeDone changes the default id to the peer's node id.
|
// handshakeDone changes the default id to the peer's node id.
|
||||||
func (c *meteredConn) handshakeDone(id discover.NodeID) {
|
func (c *meteredConn) handshakeDone(id discover.NodeID) {
|
||||||
c.ingressMeter.Stop()
|
|
||||||
c.egressMeter.Stop()
|
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
|
c.id = id.String()
|
||||||
autoKey := c.key
|
key := fmt.Sprintf("%s/%s", c.ip, c.id)
|
||||||
key := fmt.Sprintf("%s/%s", c.ip, id.String())
|
c.ingressMeter = metrics.NewRegisteredMeter(key, PeerIngressRegistry)
|
||||||
ingressMeter := metrics.NewRegisteredMeter(key, PeerIngressRegistry)
|
c.egressMeter = metrics.NewRegisteredMeter(key, PeerEgressRegistry)
|
||||||
egressMeter := metrics.NewRegisteredMeter(key, PeerEgressRegistry)
|
|
||||||
ingressMeter.Mark(c.ingressMeter.Count())
|
|
||||||
egressMeter.Mark(c.egressMeter.Count())
|
|
||||||
PeerIngressRegistry.Unregister(c.key)
|
|
||||||
PeerEgressRegistry.Unregister(c.key)
|
|
||||||
c.key = key
|
|
||||||
c.ingressMeter = ingressMeter
|
|
||||||
c.egressMeter = egressMeter
|
|
||||||
|
|
||||||
c.lock.Unlock()
|
c.lock.Unlock()
|
||||||
|
|
||||||
metricsFeed.handshake.Send(PeerHandshakeEvent{
|
metricsFeed.connect.Send(PeerConnectEvent{
|
||||||
AutoKey: autoKey,
|
IP: c.ip,
|
||||||
Key: key,
|
ID: id.String(),
|
||||||
//Ingress: nil,
|
Connected: c.connected,
|
||||||
//Egress: nil,
|
|
||||||
Handshake: time.Now(),
|
Handshake: time.Now(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -542,7 +542,7 @@ func (srv *Server) Start() (err error) {
|
||||||
|
|
||||||
srv.loopWG.Add(1)
|
srv.loopWG.Add(1)
|
||||||
go srv.run(dialer)
|
go srv.run(dialer)
|
||||||
go startTrafficNotifier(2 * time.Second)
|
go runMetricsFeedHelper(5 * time.Second)
|
||||||
srv.running = true
|
srv.running = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue