From 40624b83d209bf5b5a7fad6f637071efd05b378f Mon Sep 17 00:00:00 2001 From: Alexey Orlenko Date: Fri, 25 Apr 2025 20:04:56 +0200 Subject: [PATCH] Consume the `Responses` in `Statement::drop` Instead of dropping the `Responses` in `Statement::drop` and closing the channel stored in there, poll the response messages from it. --- tokio-postgres/Cargo.toml | 2 +- tokio-postgres/src/statement.rs | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 77b0ec700..d619c19ce 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -60,7 +60,7 @@ phf = "0.11" postgres-protocol = { version = "0.6.8", path = "../postgres-protocol" } postgres-types = { version = "0.2.9", path = "../postgres-types" } socket2 = "0.5.3" -tokio = { version = "1.27", features = ["io-util"] } +tokio = { version = "1.27", features = ["io-util", "rt"] } tokio-util = { version = "0.7", features = ["codec"] } rand = "0.9.0" whoami = "1.4.1" diff --git a/tokio-postgres/src/statement.rs b/tokio-postgres/src/statement.rs index bf9db30bb..1e9aba5fb 100644 --- a/tokio-postgres/src/statement.rs +++ b/tokio-postgres/src/statement.rs @@ -2,6 +2,7 @@ use crate::client::InnerClient; use crate::codec::FrontendMessage; use crate::connection::RequestMessages; use crate::types::Type; +use postgres_protocol::message::backend::Message; use postgres_protocol::message::frontend; use std::fmt; use std::sync::{Arc, Weak}; @@ -19,13 +20,28 @@ impl Drop for StatementInner { // Unnamed statements don't need to be closed return; } + if let Some(client) = self.client.upgrade() { let buf = client.with_buf(|buf| { frontend::close(b'S', &self.name, buf).unwrap(); frontend::sync(buf); buf.split().freeze() }); - let _ = client.send(RequestMessages::Single(FrontendMessage::Raw(buf))); + + let response = client.send(RequestMessages::Single(FrontendMessage::Raw(buf))); + + tokio::spawn(async move { + let result = async move { + match response?.next().await? { + Message::CloseComplete => Ok(()), + _ => Err(crate::Error::unexpected_message()), + } + }; + + if let Err(err) = result.await { + log::error!("failed to deallocate prepared statement: {err}"); + } + }); } } }