1use super::{CANCEL_REQUEST_CODE, PgConnection, PgResult};
4use tokio::io::AsyncWriteExt;
5use tokio::net::TcpStream;
6
7#[derive(Debug, Clone)]
10pub struct CancelToken {
11 pub(crate) host: String,
12 pub(crate) port: u16,
13 pub(crate) process_id: i32,
14 pub(crate) secret_key: i32,
15}
16
17impl CancelToken {
18 pub async fn cancel_query(&self) -> PgResult<()> {
21 PgConnection::cancel_query(&self.host, self.port, self.process_id, self.secret_key).await
22 }
23}
24
25impl PgConnection {
26 pub fn get_cancel_key(&self) -> (i32, i32) {
28 (self.process_id, self.secret_key)
29 }
30
31 pub async fn cancel_query(
35 host: &str,
36 port: u16,
37 process_id: i32,
38 secret_key: i32,
39 ) -> PgResult<()> {
40 let addr = format!("{}:{}", host, port);
42 let mut stream = TcpStream::connect(&addr).await?;
43
44 let mut buf = [0u8; 16];
47 buf[0..4].copy_from_slice(&16i32.to_be_bytes()); buf[4..8].copy_from_slice(&CANCEL_REQUEST_CODE.to_be_bytes());
49 buf[8..12].copy_from_slice(&process_id.to_be_bytes());
50 buf[12..16].copy_from_slice(&secret_key.to_be_bytes());
51
52 stream.write_all(&buf).await?;
53
54 Ok(())
56 }
57}