Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit 9ddbd85

Browse files
authored
fix: Retry RTC connection attempts multiple times (#348)
* fix: Retry RTC connection attempts multiple times * Fix test race with retryInterval
1 parent 0021226 commit 9ddbd85

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

wsnet/listen.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"cdr.dev/coder-cli/coder-sdk"
1919
)
2020

21-
var keepAliveInterval = 5 * time.Second
21+
var connectionRetryInterval = time.Second
2222

2323
// Listen connects to the broker proxies connections to the local net.
2424
// Close will end all RTC connections.
@@ -41,8 +41,19 @@ func Listen(ctx context.Context, broker string) (io.Closer, error) {
4141
// If we hit an EOF, then the connection to the broker
4242
// was interrupted. We'll take a short break then dial
4343
// again.
44-
time.Sleep(time.Second)
45-
ch, err = l.dial(ctx)
44+
ticker := time.NewTicker(connectionRetryInterval)
45+
for {
46+
select {
47+
case <-ticker.C:
48+
ch, err = l.dial(ctx)
49+
case <-ctx.Done():
50+
err = ctx.Err()
51+
}
52+
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
53+
break
54+
}
55+
}
56+
ticker.Stop()
4657
}
4758
if err != nil {
4859
l.acceptError = err
@@ -79,7 +90,6 @@ func (l *listener) dial(ctx context.Context) (<-chan error, error) {
7990
l.ws = conn
8091
nconn := websocket.NetConn(ctx, conn, websocket.MessageBinary)
8192
config := yamux.DefaultConfig()
82-
config.KeepAliveInterval = keepAliveInterval
8393
config.LogOutput = io.Discard
8494
session, err := yamux.Server(nconn, config)
8595
if err != nil {

wsnet/listen_test.go

+16-6
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,27 @@ import (
1111
"nhooyr.io/websocket"
1212
)
1313

14+
func init() {
15+
// We override this value to make tests faster.
16+
connectionRetryInterval = 10 * time.Millisecond
17+
}
18+
1419
func TestListen(t *testing.T) {
1520
t.Run("Reconnect", func(t *testing.T) {
16-
keepAliveInterval = 50 * time.Millisecond
17-
1821
var (
19-
connCh = make(chan interface{})
22+
connCh = make(chan *websocket.Conn)
2023
mux = http.NewServeMux()
2124
srv = http.Server{
2225
Handler: mux,
2326
}
2427
)
2528
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
26-
_, err := websocket.Accept(w, r, nil)
29+
ws, err := websocket.Accept(w, r, nil)
2730
if err != nil {
2831
t.Error(err)
2932
return
3033
}
31-
connCh <- struct{}{}
34+
connCh <- ws
3235
})
3336

3437
listener, err := net.Listen("tcp4", "127.0.0.1:0")
@@ -47,8 +50,15 @@ func TestListen(t *testing.T) {
4750
t.Error(err)
4851
return
4952
}
50-
<-connCh
53+
conn := <-connCh
5154
_ = listener.Close()
55+
// We need to close the connection too... closing a TCP
56+
// listener does not close active local connections.
57+
_ = conn.Close(websocket.StatusGoingAway, "")
58+
59+
// At least a few retry attempts should be had...
60+
time.Sleep(connectionRetryInterval * 5)
61+
5262
listener, err = net.Listen("tcp4", addr.String())
5363
if err != nil {
5464
t.Error(err)

0 commit comments

Comments
 (0)