Skip to content

Commit

Permalink
backend: Change COMPLETE message error to info
Browse files Browse the repository at this point in the history
COMPLETE messages are not critical for functionality since the client
will continue to receive updates even if the COMPLETE message fails.
Changed the log level to reduce noise in error logs while maintaining
visibility through info logs.

Signed-off-by: Kautilya Tripathi <[email protected]>
  • Loading branch information
knrt10 committed Jan 6, 2025
1 parent 0fb7ee9 commit 9c0d977
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 5 deletions.
9 changes: 5 additions & 4 deletions backend/cmd/multiplexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,6 @@ func (m *Multiplexer) sendIfNewResourceVersion(
// sendCompleteMessage sends a COMPLETE message to the client.
func (m *Multiplexer) sendCompleteMessage(conn *Connection, clientConn *websocket.Conn) error {
conn.mu.RLock()

if conn.closed {
conn.mu.RUnlock()
return nil // Connection is already closed, no need to send message
Expand All @@ -602,9 +601,11 @@ func (m *Multiplexer) sendCompleteMessage(conn *Connection, clientConn *websocke
conn.writeMu.Lock()
defer conn.writeMu.Unlock()

if err := clientConn.WriteJSON(completeMsg); err != nil {
logger.Log(logger.LevelError, nil, err, "writing complete message")
return err
err := clientConn.WriteJSON(completeMsg)
if err != nil {
logger.Log(logger.LevelInfo, nil, err, "connection closed while writing complete message")

return nil // Just return nil for any error - connection is dead anyway
}

return nil
Expand Down
62 changes: 61 additions & 1 deletion backend/cmd/multiplexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,67 @@ func TestSendCompleteMessage_ClosedConnection(t *testing.T) {
// Test with closed connection
clientConn.Close()
err = m.sendCompleteMessage(conn, clientConn)
assert.Error(t, err)
assert.NoError(t, err)
}

func TestSendCompleteMessage_ErrorConditions(t *testing.T) {
tests := []struct {
name string
setupConn func(*Connection, *websocket.Conn)
expectedError bool
}{
{
name: "connection already marked as closed",
setupConn: func(conn *Connection, _ *websocket.Conn) {
conn.closed = true
},
expectedError: false,
},
{
name: "normal closure",
setupConn: func(_ *Connection, clientConn *websocket.Conn) {
//nolint:errcheck
clientConn.WriteMessage(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
clientConn.Close()
},
expectedError: false,
},
{
name: "unexpected close error",
setupConn: func(_ *Connection, clientConn *websocket.Conn) {
//nolint:errcheck
clientConn.WriteMessage(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseProtocolError, ""))
clientConn.Close()
},
expectedError: false, // All errors return nil now
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
m := NewMultiplexer(kubeconfig.NewContextStore())
clientConn, clientServer := createTestWebSocketConnection()
defer clientServer.Close()

conn := &Connection{
ClusterID: "test-cluster",
Path: "/api/v1/pods",
UserID: "test-user",
Query: "watch=true",
}

tt.setupConn(conn, clientConn)
err := m.sendCompleteMessage(conn, clientConn)

if tt.expectedError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}

func createMockKubeAPIServer() *httptest.Server {
Expand Down

0 comments on commit 9c0d977

Please sign in to comment.