mirror of
https://github.com/postgresml/pgcat.git
synced 2026-03-27 18:56:30 +00:00
Better handling extended protocol messages in the event of busy pool (#155)
* Better handling for checkout errors during extended protocol messages * Fix specs * comment
This commit is contained in:
committed by
GitHub
parent
36339bd96f
commit
7f20dc3054
@@ -600,12 +600,6 @@ where
|
|||||||
message_result = read_message(&mut self.read) => message_result?
|
message_result = read_message(&mut self.read) => message_result?
|
||||||
};
|
};
|
||||||
|
|
||||||
// Avoid taking a server if the client just wants to disconnect.
|
|
||||||
if message[0] as char == 'X' {
|
|
||||||
debug!("Client disconnecting");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle admin database queries.
|
// Handle admin database queries.
|
||||||
if self.admin {
|
if self.admin {
|
||||||
debug!("Handling admin command");
|
debug!("Handling admin command");
|
||||||
@@ -613,6 +607,25 @@ where
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match message[0] as char {
|
||||||
|
// Buffer extended protocol messages even if we do not have
|
||||||
|
// a server connection yet. Hopefully, when we get the S message
|
||||||
|
// we'll be able to allocate a connection. Also, clients do not expect
|
||||||
|
// the server to respond to these messages so even if we were not able to
|
||||||
|
// allocate a connection, we wouldn't be able to send back an error message
|
||||||
|
// to the client so we buffer them and defer the decision to error out or not
|
||||||
|
// to when we get the S message
|
||||||
|
'P' | 'B' | 'D' | 'E' => {
|
||||||
|
self.buffer.put(&message[..]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
'X' => {
|
||||||
|
debug!("Client disconnecting");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
// Get a pool instance referenced by the most up-to-date
|
// Get a pool instance referenced by the most up-to-date
|
||||||
// pointer. This ensures we always read the latest config
|
// pointer. This ensures we always read the latest config
|
||||||
// when starting a query.
|
// when starting a query.
|
||||||
@@ -714,22 +727,17 @@ where
|
|||||||
conn
|
conn
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// Clients do not expect to get SystemError followed by ReadyForQuery in the middle
|
// Client is attempting to get results from the server,
|
||||||
// of extended protocol submission. So we will hold off on sending the actual error
|
// but we were unable to grab a connection from the pool
|
||||||
// message to the client until we get 'S' message
|
// We'll send back an error message and clean the extended
|
||||||
match message[0] as char {
|
// protocol buffer
|
||||||
'P' | 'B' | 'E' | 'D' => (),
|
if message[0] as char == 'S' {
|
||||||
_ => {
|
error!("Got Sync message but failed to get a connection from the pool");
|
||||||
error_response(
|
self.buffer.clear();
|
||||||
&mut self.write,
|
}
|
||||||
"could not get connection from the pool",
|
error_response(&mut self.write, "could not get connection from the pool")
|
||||||
)
|
.await?;
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
error!("Could not get connection from pool: {:?}", err);
|
error!("Could not get connection from pool: {:?}", err);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user