Skip to content

Ping sometimes causes Close to time out #298

@univerio

Description

@univerio

Minimal reproduction:

package websocket_test

import (
	"context"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"nhooyr.io/websocket"
	"nhooyr.io/websocket/internal/test/wstest"
)

func TestWeirdTimeout(t *testing.T) {
	sConn, cConn := wstest.Pipe(nil, nil)
	sConn.CloseRead(context.Background())
	cConn.CloseRead(context.Background())
	go func() {
		for range time.Tick(10 * time.Millisecond) {
			if err := sConn.Ping(context.Background()); err != nil {
				return
			}
		}
	}()

	time.Sleep(30 * time.Millisecond)
	assert.NoError(t, sConn.Close(websocket.StatusNormalClosure, ""))
}

This seems to non-deterministically fail with the documented 5s timeout:

$ go test -run TestWeirdTimeout -count 100 -failfast -v
=== RUN   TestWeirdTimeout
--- PASS: TestWeirdTimeout (0.03s)
=== RUN   TestWeirdTimeout
--- PASS: TestWeirdTimeout (0.03s)
=== RUN   TestWeirdTimeout
--- PASS: TestWeirdTimeout (0.03s)
=== RUN   TestWeirdTimeout
    foo_test.go:26:
        	Error Trace:	foo_test.go:26
        	Error:      	Received unexpected error:
        	            	failed to close WebSocket: failed to write control frame opClose: failed to write frame: context deadline exceeded
        	Test:       	TestWeirdTimeout
--- FAIL: TestWeirdTimeout (5.03s)
FAIL
exit status 1
FAIL	nhooyr.io/websocket	5.309s

Is it incorrect to call Close() concurrently with Ping()?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions