Skip to content

Commit aa15a63

Browse files
committed
derp: add new concurrent server benchmark
In prep for reducing mutex contention on Server.mu. Updates tailscale#3560 Change-Id: Ie95e7c6dc9f4b64b6f79b3b2338f8cd86c688d98 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 parent 3bee38d commit aa15a63

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

derp/derp_client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ func newClient(privateKey key.NodePrivate, nc Conn, brw *bufio.ReadWriter, logf
121121
return c, nil
122122
}
123123

124+
func (c *Client) PublicKey() key.NodePublic { return c.publicKey }
125+
124126
func (c *Client) recvServerKey() error {
125127
var buf [40]byte
126128
t, flen, err := readFrame(c.br, 1<<10, buf[:])

derp/derp_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,72 @@ func TestLimiter(t *testing.T) {
13111311
}
13121312
}
13131313

1314+
// BenchmarkConcurrentStreams exercises mutex contention on a
1315+
// single Server instance with multiple concurrent client flows.
1316+
func BenchmarkConcurrentStreams(b *testing.B) {
1317+
serverPrivateKey := key.NewNode()
1318+
s := NewServer(serverPrivateKey, logger.Discard)
1319+
defer s.Close()
1320+
1321+
ln, err := net.Listen("tcp", "127.0.0.1:0")
1322+
if err != nil {
1323+
b.Fatal(err)
1324+
}
1325+
defer ln.Close()
1326+
1327+
ctx, cancel := context.WithCancel(context.Background())
1328+
defer cancel()
1329+
1330+
go func() {
1331+
for ctx.Err() == nil {
1332+
connIn, err := ln.Accept()
1333+
if err != nil {
1334+
if ctx.Err() != nil {
1335+
return
1336+
}
1337+
b.Error(err)
1338+
return
1339+
}
1340+
1341+
brwServer := bufio.NewReadWriter(bufio.NewReader(connIn), bufio.NewWriter(connIn))
1342+
go s.Accept(ctx, connIn, brwServer, "test-client")
1343+
}
1344+
}()
1345+
1346+
newClient := func(t testing.TB) *Client {
1347+
t.Helper()
1348+
connOut, err := net.Dial("tcp", ln.Addr().String())
1349+
if err != nil {
1350+
b.Fatal(err)
1351+
}
1352+
t.Cleanup(func() { connOut.Close() })
1353+
1354+
k := key.NewNode()
1355+
1356+
brw := bufio.NewReadWriter(bufio.NewReader(connOut), bufio.NewWriter(connOut))
1357+
client, err := NewClient(k, connOut, brw, logger.Discard)
1358+
if err != nil {
1359+
b.Fatalf("client: %v", err)
1360+
}
1361+
return client
1362+
}
1363+
1364+
b.RunParallel(func(pb *testing.PB) {
1365+
c1, c2 := newClient(b), newClient(b)
1366+
const packetSize = 100
1367+
msg := make([]byte, packetSize)
1368+
for pb.Next() {
1369+
if err := c1.Send(c2.PublicKey(), msg); err != nil {
1370+
b.Fatal(err)
1371+
}
1372+
_, err := c2.Recv()
1373+
if err != nil {
1374+
return
1375+
}
1376+
}
1377+
})
1378+
}
1379+
13141380
func BenchmarkSendRecv(b *testing.B) {
13151381
for _, size := range []int{10, 100, 1000, 10000} {
13161382
b.Run(fmt.Sprintf("msgsize=%d", size), func(b *testing.B) { benchmarkSendRecvSize(b, size) })

0 commit comments

Comments
 (0)