Skip to content

Commit 9d402f8

Browse files
authored
perf: reduce metrics hot-path lock contention (#72)
1 parent dfdb552 commit 9d402f8

File tree

3 files changed

+16
-18
lines changed

3 files changed

+16
-18
lines changed

elastictransport/elastictransport.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,7 @@ func (c *Client) Perform(req *http.Request) (*http.Response, error) {
327327

328328
// Record metrics, when enabled
329329
if c.metrics != nil {
330-
c.metrics.Lock()
331-
c.metrics.requests++
332-
c.metrics.Unlock()
330+
c.metrics.requests.Add(1)
333331
}
334332

335333
// Update request
@@ -418,9 +416,7 @@ func (c *Client) Perform(req *http.Request) (*http.Response, error) {
418416
if err != nil {
419417
// Record metrics, when enabled
420418
if c.metrics != nil {
421-
c.metrics.Lock()
422-
c.metrics.failures++
423-
c.metrics.Unlock()
419+
c.metrics.failures.Add(1)
424420
}
425421

426422
// Report the connection as unsuccessful

elastictransport/metrics.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"strconv"
2424
"strings"
2525
"sync"
26+
"sync/atomic"
2627
"time"
2728
)
2829

@@ -63,8 +64,8 @@ type ConnectionMetric struct {
6364
type metrics struct {
6465
sync.RWMutex
6566

66-
requests int
67-
failures int
67+
requests atomic.Uint64
68+
failures atomic.Uint64
6869
responses map[int]int
6970
}
7071

@@ -73,20 +74,21 @@ func (c *Client) Metrics() (Metrics, error) {
7374
if c.metrics == nil {
7475
return Metrics{}, errors.New("transport metrics not enabled")
7576
}
76-
c.metrics.RLock()
77-
defer c.metrics.RUnlock()
7877

7978
c.poolMu.RLock()
8079
defer c.poolMu.RUnlock()
8180

82-
m := Metrics{
83-
Requests: c.metrics.requests,
84-
Failures: c.metrics.failures,
85-
Responses: make(map[int]int, len(c.metrics.responses)),
81+
responses := make(map[int]int)
82+
c.metrics.RLock()
83+
for code, num := range c.metrics.responses {
84+
responses[code] = num
8685
}
86+
c.metrics.RUnlock()
8787

88-
for code, num := range c.metrics.responses {
89-
m.Responses[code] = num
88+
m := Metrics{
89+
Requests: int(c.metrics.requests.Load()),
90+
Failures: int(c.metrics.failures.Load()),
91+
Responses: responses,
9092
}
9193

9294
if pool, ok := c.pool.(connectionable); ok {

elastictransport/metrics_internal_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ func TestMetrics(t *testing.T) {
4949
},
5050
)
5151

52-
tp.metrics.requests = 3
53-
tp.metrics.failures = 4
52+
tp.metrics.requests.Store(3)
53+
tp.metrics.failures.Store(4)
5454
tp.metrics.responses[200] = 1
5555
tp.metrics.responses[404] = 2
5656

0 commit comments

Comments
 (0)