Skip to content

Commit

Permalink
swarm: use a sync.Pool to make metrics collection allocation-free
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Jan 7, 2023
1 parent f6b2ad9 commit 45eb893
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 16 deletions.
55 changes: 39 additions & 16 deletions p2p/net/swarm/swarm_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"net"
"strings"
"sync"
"time"

"github.com/libp2p/go-libp2p/core/crypto"
Expand Down Expand Up @@ -69,6 +70,19 @@ func init() {
prometheus.MustRegister(connsOpened, keyTypes, connsClosed, dialError, connDuration, connHandshakeLatency)
}

var stringPool = sync.Pool{New: func() any {
s := make([]string, 0, 8)
return &s
}}

func getStringSlice() *[]string {
s := stringPool.Get().(*[]string)
*s = (*s)[:0]
return s
}

func putStringSlice(s *[]string) { stringPool.Put(s) }

var transports = [...]int{ma.P_CIRCUIT, ma.P_WEBRTC, ma.P_WEBTRANSPORT, ma.P_QUIC, ma.P_QUIC_V1, ma.P_WSS, ma.P_WS, ma.P_TCP}

func getDirection(dir network.Direction) string {
Expand Down Expand Up @@ -97,31 +111,40 @@ func appendConnectionState(tags []string, cs network.ConnectionState) []string {
}

func recordConnectionOpened(dir network.Direction, p crypto.PubKey, cs network.ConnectionState) {
tags := make([]string, 0, 4)
tags = append(tags, getDirection(dir))
tags = appendConnectionState(tags, cs)
connsOpened.WithLabelValues(tags...).Inc()
keyTypes.WithLabelValues(getDirection(dir), p.Type().String()).Inc()
tags := getStringSlice()
defer putStringSlice(tags)

*tags = append(*tags, getDirection(dir))
*tags = appendConnectionState(*tags, cs)
connsOpened.WithLabelValues(*tags...).Inc()

*tags = (*tags)[:0]
*tags = append(*tags, getDirection(dir))
*tags = append(*tags, p.Type().String())
keyTypes.WithLabelValues(*tags...).Inc()
}

func recordConnectionClosed(dir network.Direction, cs network.ConnectionState) {
tags := make([]string, 0, 4)
tags = append(tags, getDirection(dir))
tags = appendConnectionState(tags, cs)
connsClosed.WithLabelValues(tags...).Inc()
tags := getStringSlice()
defer putStringSlice(tags)
*tags = append(*tags, getDirection(dir))
*tags = appendConnectionState(*tags, cs)
connsClosed.WithLabelValues(*tags...).Inc()
}

func recordConnectionDuration(dir network.Direction, t time.Duration, cs network.ConnectionState) {
tags := make([]string, 0, 4)
tags = append(tags, getDirection(dir))
tags = appendConnectionState(tags, cs)
connDuration.WithLabelValues(tags...).Observe(t.Seconds())
tags := getStringSlice()
defer putStringSlice(tags)
*tags = append(*tags, getDirection(dir))
*tags = appendConnectionState(*tags, cs)
connDuration.WithLabelValues(*tags...).Observe(t.Seconds())
}

func recordHandshakeLatency(t time.Duration, cs network.ConnectionState) {
tags := make([]string, 0, 3)
tags = appendConnectionState(tags, cs)
connHandshakeLatency.WithLabelValues(tags...).Observe(t.Seconds())
tags := getStringSlice()
defer putStringSlice(tags)
*tags = appendConnectionState(*tags, cs)
connHandshakeLatency.WithLabelValues(*tags...).Observe(t.Seconds())
}

func recordDialFailed(addr ma.Multiaddr, err error) {
Expand Down
31 changes: 31 additions & 0 deletions p2p/net/swarm/swarm_metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package swarm

import (
"crypto/rand"
"testing"

"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/network"

"github.com/stretchr/testify/require"
)

func BenchmarkMetricsConnOpen(b *testing.B) {
b.ReportAllocs()
quicConnState := network.ConnectionState{Transport: "quic"}
tcpConnState := network.ConnectionState{
StreamMultiplexer: "yamux",
Security: "tls",
Transport: "tcp",
}
_, pub, err := crypto.GenerateEd25519Key(rand.Reader)
require.NoError(b, err)
for i := 0; i < b.N; i++ {
switch i % 2 {
case 0:
recordConnectionOpened(network.DirInbound, pub, quicConnState)
case 1:
recordConnectionOpened(network.DirInbound, pub, tcpConnState)
}
}
}

0 comments on commit 45eb893

Please sign in to comment.