MCPcopy Index your code
hub / github.com/coder/coder / heartbeatCloseWith

Function heartbeatCloseWith

coderd/httpapi/websocket.go:30–64  ·  view source on GitHub ↗
(ctx context.Context, logger slog.Logger, exit func(), conn *websocket.Conn, clk quartz.Clock, interval time.Duration)

Source from the content-addressed store, hash-verified

28}
29
30func heartbeatCloseWith(ctx context.Context, logger slog.Logger, exit func(), conn *websocket.Conn, clk quartz.Clock, interval time.Duration) {
31 ticker := clk.NewTicker(interval, "HeartbeatClose")
32 defer ticker.Stop()
33
34 for {
35 select {
36 case <-ctx.Done():
37 return
38 case <-ticker.C:
39 }
40 err := pingWithTimeout(ctx, conn, interval)
41 if err != nil {
42 // These errors are all expected during normal connection
43 // teardown and should not be logged at error level:
44 // - context.DeadlineExceeded: client disconnected
45 // without sending a close frame.
46 // - context.Canceled: request context was canceled.
47 // - net.ErrClosed: connection was already closed by
48 // another goroutine (e.g. handler returned).
49 // - websocket.CloseError: a close frame was
50 // received or sent.
51 if errors.Is(err, context.DeadlineExceeded) ||
52 errors.Is(err, context.Canceled) ||
53 errors.Is(err, net.ErrClosed) ||
54 websocket.CloseStatus(err) != -1 {
55 logger.Debug(ctx, "heartbeat ping stopped", slog.Error(err))
56 } else {
57 logger.Error(ctx, "failed to heartbeat ping", slog.Error(err))
58 }
59 _ = conn.Close(websocket.StatusGoingAway, "Ping failed")
60 exit()
61 return
62 }
63 }
64}
65
66func pingWithTimeout(ctx context.Context, conn *websocket.Conn, timeout time.Duration) error {
67 ctx, cancel := context.WithTimeout(ctx, timeout)

Callers 3

TestHeartbeatCloseFunction · 0.85
HeartbeatCloseFunction · 0.85
HeartbeatCloseWithClockFunction · 0.85

Calls 6

pingWithTimeoutFunction · 0.85
StopMethod · 0.65
CloseMethod · 0.65
DoneMethod · 0.45
IsMethod · 0.45
ErrorMethod · 0.45

Tested by 1

TestHeartbeatCloseFunction · 0.68