Files
Spike Curtis 2c7f8ac65f chore: migrate to coder/websocket 1.8.12 (#15898)
Migrates us to `coder/websocket` v1.8.12 rather than `nhooyr/websocket` on an older version.

Works around https://github.com/coder/websocket/issues/504 by adding an explicit test for `xerrors.Is(err, io.EOF)` where we were previously getting `io.EOF` from the netConn.
2024-12-19 00:51:30 +04:00

71 lines
1.4 KiB
Go

package workspacetraffic
import (
"context"
"errors"
"io"
"time"
"golang.org/x/xerrors"
"github.com/coder/websocket"
)
// countReadWriteCloser wraps an io.ReadWriteCloser and counts the number of bytes read and written.
type countReadWriteCloser struct {
rwc io.ReadWriteCloser
readMetrics ConnMetrics
writeMetrics ConnMetrics
}
func (w *countReadWriteCloser) Close() error {
return w.rwc.Close()
}
func (w *countReadWriteCloser) Read(p []byte) (int, error) {
start := time.Now()
n, err := w.rwc.Read(p)
took := time.Since(start).Seconds()
if reportableErr(err) {
w.readMetrics.AddError(1)
}
w.readMetrics.ObserveLatency(took)
if n > 0 {
w.readMetrics.AddTotal(float64(n))
}
return n, err
}
func (w *countReadWriteCloser) Write(p []byte) (int, error) {
start := time.Now()
n, err := w.rwc.Write(p)
took := time.Since(start).Seconds()
if reportableErr(err) {
w.writeMetrics.AddError(1)
}
w.writeMetrics.ObserveLatency(took)
if n > 0 {
w.writeMetrics.AddTotal(float64(n))
}
return n, err
}
// some errors we want to report in metrics; others we want to ignore
// such as websocket.StatusNormalClosure or context.Canceled
func reportableErr(err error) bool {
if err == nil {
return false
}
if xerrors.Is(err, io.EOF) {
return false
}
if xerrors.Is(err, context.Canceled) {
return false
}
var wsErr websocket.CloseError
if errors.As(err, &wsErr) {
return wsErr.Code != websocket.StatusNormalClosure
}
return false
}