Fix memory leak (#3066)

This commit is contained in:
Tobie Morgan Hitchcock 2023-12-05 09:28:29 +00:00 committed by GitHub
parent 3b5a7411cf
commit 08ec62cbe1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -180,19 +180,17 @@ impl Connection {
// Check if this has shutdown // Check if this has shutdown
_ = canceller.cancelled() => break, _ = canceller.cancelled() => break,
// Wait for the next message to send // Wait for the next message to send
msg = internal_receiver.next() => { Some(res) = internal_receiver.next() => {
if let Some(res) = msg { // Send the message to the client
// Send the message to the client if let Err(err) = sender.send(res).await {
if let Err(err) = sender.send(res).await { // Output any errors if not a close error
// Output any errors if not a close error if err.to_string() != CONN_CLOSED_ERR {
if err.to_string() != CONN_CLOSED_ERR { debug!("WebSocket error: {:?}", err);
debug!("WebSocket error: {:?}", err);
}
// Cancel the WebSocket tasks
rpc.read().await.canceller.cancel();
// Exit out of the loop
break;
} }
// Cancel the WebSocket tasks
rpc.read().await.canceller.cancel();
// Exit out of the loop
break;
} }
}, },
} }
@ -216,42 +214,51 @@ impl Connection {
biased; biased;
// Check if this has shutdown // Check if this has shutdown
_ = canceller.cancelled() => break, _ = canceller.cancelled() => break,
// Wait for the next message to read // Remove any completed tasks
msg = receiver.next() => { Some(out) = tasks.join_next() => match out {
if let Some(msg) = msg { // The task completed successfully
// Process the received WebSocket message Ok(_) => continue,
match msg { // There was an uncaught panic in the task
// We've received a message from the client Err(err) => {
Ok(msg) => match msg { // There was an error with the task
Message::Text(_) => { trace!("WebSocket request error: {:?}", err);
tasks.spawn(Connection::handle_message(rpc.clone(), msg, internal_sender.clone())); // Cancel the WebSocket tasks
} rpc.read().await.canceller.cancel();
Message::Binary(_) => { // Exit out of the loop
tasks.spawn(Connection::handle_message(rpc.clone(), msg, internal_sender.clone())); break;
} }
Message::Close(_) => { },
// Respond with a close message // Wait for the next received message
if let Err(err) = internal_sender.send(Message::Close(None)).await { Some(msg) = receiver.next() => match msg {
trace!("WebSocket error when replying to the Close frame: {:?}", err); // We've received a message from the client
}; Ok(msg) => match msg {
// Cancel the WebSocket tasks Message::Text(_) => {
rpc.read().await.canceller.cancel(); tasks.spawn(Connection::handle_message(rpc.clone(), msg, internal_sender.clone()));
// Exit out of the loop
break;
}
_ => {
// Ignore everything else
}
},
Err(err) => {
// There was an error with the WebSocket
trace!("WebSocket error: {:?}", err);
// Cancel the WebSocket tasks
rpc.read().await.canceller.cancel();
// Exit out of the loop
break;
}
} }
Message::Binary(_) => {
tasks.spawn(Connection::handle_message(rpc.clone(), msg, internal_sender.clone()));
}
Message::Close(_) => {
// Respond with a close message
if let Err(err) = internal_sender.send(Message::Close(None)).await {
trace!("WebSocket error when replying to the Close frame: {:?}", err);
};
// Cancel the WebSocket tasks
rpc.read().await.canceller.cancel();
// Exit out of the loop
break;
}
_ => {
// Ignore everything else
}
},
Err(err) => {
// There was an error with the WebSocket
trace!("WebSocket error: {:?}", err);
// Cancel the WebSocket tasks
rpc.read().await.canceller.cancel();
// Exit out of the loop
break;
} }
} }
} }
@ -259,9 +266,12 @@ impl Connection {
// Wait for all tasks to finish // Wait for all tasks to finish
while let Some(res) = tasks.join_next().await { while let Some(res) = tasks.join_next().await {
if let Err(err) = res { if let Err(err) = res {
error!("Error while handling RPC message: {}", err); // There was an error with the task
trace!("WebSocket request error: {:?}", err);
} }
} }
// Abort all tasks
tasks.shutdown().await;
} }
/// Send live query notifications to the client /// Send live query notifications to the client