Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1347916

Browse files
committed
remove latency, use quartz
1 parent a3f95e8 commit 1347916

File tree

5 files changed

+160
-201
lines changed

5 files changed

+160
-201
lines changed

vpn/client.go

-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ import (
55
"net/http"
66
"net/netip"
77
"net/url"
8-
"time"
98

109
"golang.org/x/xerrors"
1110
"nhooyr.io/websocket"
12-
"tailscale.com/ipn/ipnstate"
1311
"tailscale.com/net/dns"
1412
"tailscale.com/wgengine/router"
1513

@@ -27,7 +25,6 @@ import (
2725
type Conn interface {
2826
CurrentWorkspaceState() (tailnet.WorkspaceUpdate, error)
2927
GetPeerDiagnostics(peerID uuid.UUID) tailnet.PeerDiagnostics
30-
Ping(ctx context.Context, ip netip.Addr) (time.Duration, bool, *ipnstate.PingResult, error)
3128
Close() error
3229
}
3330

vpn/tunnel.go

+15-21
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717

1818
"golang.org/x/exp/maps"
1919
"golang.org/x/xerrors"
20-
"google.golang.org/protobuf/types/known/durationpb"
2120
"google.golang.org/protobuf/types/known/timestamppb"
2221
"tailscale.com/net/dns"
2322
"tailscale.com/util/dnsname"
@@ -28,10 +27,12 @@ import (
2827
"cdr.dev/slog"
2928
"github.com/coder/coder/v2/coderd/util/ptr"
3029
"github.com/coder/coder/v2/tailnet"
30+
"github.com/coder/quartz"
3131
)
3232

33-
// The interval at which the tunnel sends network status updates to the manager.
34-
const netStatusInterval = 30 * time.Second
33+
// netStatusInterval is the interval at which the tunnel sends network status updates to the manager.
34+
// This is currently only used to keep `last_handshake` up to date.
35+
const netStatusInterval = 10 * time.Second
3536

3637
type Tunnel struct {
3738
speaker[*TunnelMessage, *ManagerMessage, ManagerMessage]
@@ -57,6 +58,8 @@ type Tunnel struct {
5758
// router and dnsConfigurator may be nil
5859
router router.Router
5960
dnsConfigurator dns.OSConfigurator
61+
62+
clock quartz.Clock
6063
}
6164

6265
type TunnelOption func(t *Tunnel)
@@ -84,6 +87,7 @@ func NewTunnel(
8487
netLoopDone: make(chan struct{}),
8588
client: client,
8689
agents: make(map[uuid.UUID]*tailnet.Agent),
90+
clock: quartz.NewReal(),
8791
}
8892

8993
for _, opt := range opts {
@@ -121,7 +125,7 @@ func (t *Tunnel) requestLoop() {
121125
}
122126

123127
func (t *Tunnel) netStatusLoop() {
124-
ticker := time.NewTicker(netStatusInterval)
128+
ticker := t.clock.NewTicker(netStatusInterval)
125129
defer ticker.Stop()
126130
defer close(t.netLoopDone)
127131
for {
@@ -212,6 +216,12 @@ func UseAsDNSConfig() TunnelOption {
212216
}
213217
}
214218

219+
func WithClock(clock quartz.Clock) TunnelOption {
220+
return func(r *Tunnel) {
221+
r.clock = clock
222+
}
223+
}
224+
215225
// ApplyNetworkSettings sends a request to the manager to apply the given network settings
216226
func (t *Tunnel) ApplyNetworkSettings(ctx context.Context, ns *NetworkSettingsRequest) error {
217227
msg, err := t.speaker.unaryRPC(ctx, &TunnelMessage{
@@ -376,22 +386,18 @@ func (t *Tunnel) createPeerUpdate(update tailnet.WorkspaceUpdate) (*PeerUpdate,
376386
Fqdn: fqdn,
377387
IpAddrs: hostsToIPStrings(agent.Hosts),
378388
LastHandshake: nil,
379-
Latency: nil,
380389
}
381390
}
382391
return out, nil
383392
}
384393

385-
// Given a list of agents, populate their network info, and return them as proto agents.
394+
// Given a list of `tailnet.Agent`, populate their network info, and conver them to proto agents.
386395
func (t *Tunnel) populateAgents(agents []*tailnet.Agent) ([]*Agent, error) {
387396
if t.conn == nil {
388397
return nil, xerrors.New("no active connection")
389398
}
390399

391400
out := make([]*Agent, 0, len(agents))
392-
var wg sync.WaitGroup
393-
pingCtx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
394-
defer cancelFunc()
395401

396402
for _, agent := range agents {
397403
fqdn := make([]string, 0, len(agent.Hosts))
@@ -405,22 +411,10 @@ func (t *Tunnel) populateAgents(agents []*tailnet.Agent) ([]*Agent, error) {
405411
Fqdn: fqdn,
406412
IpAddrs: hostsToIPStrings(agent.Hosts),
407413
}
408-
agentIP := tailnet.CoderServicePrefix.AddrFromUUID(agent.ID)
409-
wg.Add(1)
410-
go func() {
411-
defer wg.Done()
412-
duration, _, _, err := t.conn.Ping(pingCtx, agentIP)
413-
if err != nil {
414-
return
415-
}
416-
protoAgent.Latency = durationpb.New(duration)
417-
}()
418414
diags := t.conn.GetPeerDiagnostics(agent.ID)
419-
//nolint:revive // outdated rule
420415
protoAgent.LastHandshake = timestamppb.New(diags.LastWireguardHandshake)
421416
out = append(out, protoAgent)
422417
}
423-
wg.Wait()
424418

425419
return out, nil
426420
}

vpn/tunnel_internal_test.go

+13-27
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ import (
1313

1414
"github.com/google/uuid"
1515
"github.com/stretchr/testify/require"
16-
"google.golang.org/protobuf/types/known/durationpb"
1716
"google.golang.org/protobuf/types/known/timestamppb"
18-
"tailscale.com/ipn/ipnstate"
1917
"tailscale.com/util/dnsname"
2018

2119
"github.com/coder/coder/v2/tailnet"
2220
"github.com/coder/coder/v2/tailnet/proto"
2321
"github.com/coder/coder/v2/testutil"
22+
"github.com/coder/quartz"
2423
)
2524

2625
func newFakeClient(ctx context.Context, t *testing.T) *fakeClient {
@@ -69,10 +68,6 @@ func (f *fakeConn) CurrentWorkspaceState() (tailnet.WorkspaceUpdate, error) {
6968
return f.state, nil
7069
}
7170

72-
func (*fakeConn) Ping(context.Context, netip.Addr) (time.Duration, bool, *ipnstate.PingResult, error) {
73-
return time.Millisecond * 100, true, &ipnstate.PingResult{}, nil
74-
}
75-
7671
func (f *fakeConn) GetPeerDiagnostics(uuid.UUID) tailnet.PeerDiagnostics {
7772
return tailnet.PeerDiagnostics{
7873
LastWireguardHandshake: f.hsTime,
@@ -93,7 +88,7 @@ func TestTunnel_StartStop(t *testing.T) {
9388
client := newFakeClient(ctx, t)
9489
conn := newFakeConn(tailnet.WorkspaceUpdate{}, time.Time{})
9590

96-
_, mgr := setupTunnel(t, ctx, client)
91+
_, mgr := setupTunnel(t, ctx, client, quartz.NewMock(t))
9792

9893
errCh := make(chan error, 1)
9994
var resp *TunnelMessage
@@ -159,7 +154,7 @@ func TestTunnel_PeerUpdate(t *testing.T) {
159154
},
160155
}, time.Time{})
161156

162-
tun, mgr := setupTunnel(t, ctx, client)
157+
tun, mgr := setupTunnel(t, ctx, client, quartz.NewMock(t))
163158

164159
errCh := make(chan error, 1)
165160
var resp *TunnelMessage
@@ -224,7 +219,7 @@ func TestTunnel_NetworkSettings(t *testing.T) {
224219
client := newFakeClient(ctx, t)
225220
conn := newFakeConn(tailnet.WorkspaceUpdate{}, time.Time{})
226221

227-
tun, mgr := setupTunnel(t, ctx, client)
222+
tun, mgr := setupTunnel(t, ctx, client, quartz.NewMock(t))
228223

229224
errCh := make(chan error, 1)
230225
var resp *TunnelMessage
@@ -287,7 +282,7 @@ func TestTunnel_createPeerUpdate(t *testing.T) {
287282

288283
client := newFakeClient(ctx, t)
289284

290-
tun, _ := setupTunnel(t, ctx, client)
285+
tun, _ := setupTunnel(t, ctx, client, quartz.NewMock(t))
291286
hsTime := time.Now().Add(-time.Minute).UTC()
292287
tun.conn = newFakeConn(tailnet.WorkspaceUpdate{}, hsTime)
293288

@@ -337,7 +332,6 @@ func TestTunnel_createPeerUpdate(t *testing.T) {
337332
Fqdn: []string{"w1.coder.", "w1a1.w1.me.coder.", "w1a1.w1.testy.coder."},
338333
IpAddrs: []string{w1a1IP.String()},
339334
LastHandshake: timestamppb.New(hsTime),
340-
Latency: durationpb.New(100 * time.Millisecond),
341335
},
342336
},
343337
DeletedWorkspaces: []*Workspace{
@@ -348,7 +342,6 @@ func TestTunnel_createPeerUpdate(t *testing.T) {
348342
Id: w2a1ID[:], Name: "w2a1", WorkspaceId: w2ID[:],
349343
Fqdn: []string{"w2.coder.", "w2a1.w2.me.coder.", "w2a1.w2.testy.coder."},
350344
IpAddrs: []string{w2a1IP.String()},
351-
Latency: nil,
352345
LastHandshake: nil,
353346
},
354347
},
@@ -360,6 +353,8 @@ func TestTunnel_sendAgentUpdate(t *testing.T) {
360353

361354
ctx := testutil.Context(t, testutil.WaitShort)
362355

356+
mClock := quartz.NewMock(t)
357+
363358
wID1 := uuid.UUID{1}
364359
aID1 := uuid.UUID{2}
365360
aID2 := uuid.UUID{3}
@@ -368,8 +363,7 @@ func TestTunnel_sendAgentUpdate(t *testing.T) {
368363
client := newFakeClient(ctx, t)
369364
conn := newFakeConn(tailnet.WorkspaceUpdate{}, hsTime)
370365

371-
tun, mgr := setupTunnel(t, ctx, client)
372-
366+
tun, mgr := setupTunnel(t, ctx, client, mClock)
373367
errCh := make(chan error, 1)
374368
var resp *TunnelMessage
375369
go func() {
@@ -391,9 +385,6 @@ func TestTunnel_sendAgentUpdate(t *testing.T) {
391385
_, ok := resp.Msg.(*TunnelMessage_Start)
392386
require.True(t, ok)
393387

394-
// `sendAgentUpdate` is a no-op if there's no agents
395-
tun.sendAgentUpdate()
396-
397388
// Inform the tunnel of the initial state
398389
err = tun.Update(tailnet.WorkspaceUpdate{
399390
UpsertedWorkspaces: []*tailnet.Workspace{
@@ -422,8 +413,7 @@ func TestTunnel_sendAgentUpdate(t *testing.T) {
422413
// `sendAgentUpdate` produces the same PeerUpdate message until an agent
423414
// update is received
424415
for range 2 {
425-
// When: we send a (normally scheduled) agent update
426-
tun.sendAgentUpdate()
416+
mClock.AdvanceNext()
427417
// Then: the tunnel sends a PeerUpdate message of agent upserts,
428418
// with the last handshake and latency set
429419
req = testutil.RequireRecvCtx(ctx, t, mgr.requests)
@@ -432,7 +422,6 @@ func TestTunnel_sendAgentUpdate(t *testing.T) {
432422
require.Len(t, req.msg.GetPeerUpdate().UpsertedAgents, 1)
433423
require.Equal(t, aID1[:], req.msg.GetPeerUpdate().UpsertedAgents[0].Id)
434424
require.Equal(t, hsTime, req.msg.GetPeerUpdate().UpsertedAgents[0].LastHandshake.AsTime())
435-
require.Equal(t, 100*time.Millisecond, req.msg.GetPeerUpdate().UpsertedAgents[0].Latency.AsDuration())
436425
}
437426

438427
// Upsert a new agent
@@ -453,7 +442,7 @@ func TestTunnel_sendAgentUpdate(t *testing.T) {
453442
testutil.RequireRecvCtx(ctx, t, mgr.requests)
454443

455444
// The new update includes the new agent
456-
tun.sendAgentUpdate()
445+
mClock.AdvanceNext()
457446
req = testutil.RequireRecvCtx(ctx, t, mgr.requests)
458447
require.Nil(t, req.msg.Rpc)
459448
require.NotNil(t, req.msg.GetPeerUpdate())
@@ -464,10 +453,8 @@ func TestTunnel_sendAgentUpdate(t *testing.T) {
464453

465454
require.Equal(t, aID1[:], req.msg.GetPeerUpdate().UpsertedAgents[0].Id)
466455
require.Equal(t, hsTime, req.msg.GetPeerUpdate().UpsertedAgents[0].LastHandshake.AsTime())
467-
require.Equal(t, 100*time.Millisecond, req.msg.GetPeerUpdate().UpsertedAgents[0].Latency.AsDuration())
468456
require.Equal(t, aID2[:], req.msg.GetPeerUpdate().UpsertedAgents[1].Id)
469457
require.Equal(t, hsTime, req.msg.GetPeerUpdate().UpsertedAgents[1].LastHandshake.AsTime())
470-
require.Equal(t, 100*time.Millisecond, req.msg.GetPeerUpdate().UpsertedAgents[1].Latency.AsDuration())
471458

472459
// Delete an agent
473460
err = tun.Update(tailnet.WorkspaceUpdate{
@@ -486,18 +473,17 @@ func TestTunnel_sendAgentUpdate(t *testing.T) {
486473
testutil.RequireRecvCtx(ctx, t, mgr.requests)
487474

488475
// The new update doesn't include the deleted agent
489-
tun.sendAgentUpdate()
476+
mClock.AdvanceNext()
490477
req = testutil.RequireRecvCtx(ctx, t, mgr.requests)
491478
require.Nil(t, req.msg.Rpc)
492479
require.NotNil(t, req.msg.GetPeerUpdate())
493480
require.Len(t, req.msg.GetPeerUpdate().UpsertedAgents, 1)
494481
require.Equal(t, aID2[:], req.msg.GetPeerUpdate().UpsertedAgents[0].Id)
495482
require.Equal(t, hsTime, req.msg.GetPeerUpdate().UpsertedAgents[0].LastHandshake.AsTime())
496-
require.Equal(t, 100*time.Millisecond, req.msg.GetPeerUpdate().UpsertedAgents[0].Latency.AsDuration())
497483
}
498484

499485
//nolint:revive // t takes precedence
500-
func setupTunnel(t *testing.T, ctx context.Context, client *fakeClient) (*Tunnel, *speaker[*ManagerMessage, *TunnelMessage, TunnelMessage]) {
486+
func setupTunnel(t *testing.T, ctx context.Context, client *fakeClient, mClock quartz.Clock) (*Tunnel, *speaker[*ManagerMessage, *TunnelMessage, TunnelMessage]) {
501487
mp, tp := net.Pipe()
502488
t.Cleanup(func() { _ = mp.Close() })
503489
t.Cleanup(func() { _ = tp.Close() })
@@ -507,7 +493,7 @@ func setupTunnel(t *testing.T, ctx context.Context, client *fakeClient) (*Tunnel
507493
var mgr *speaker[*ManagerMessage, *TunnelMessage, TunnelMessage]
508494
errCh := make(chan error, 2)
509495
go func() {
510-
tunnel, err := NewTunnel(ctx, logger.Named("tunnel"), tp, client)
496+
tunnel, err := NewTunnel(ctx, logger.Named("tunnel"), tp, client, WithClock(mClock))
511497
tun = tunnel
512498
errCh <- err
513499
}()

0 commit comments

Comments
 (0)