@@ -600,19 +600,32 @@ where
600
600
message_result = read_message( & mut self . read) => message_result?
601
601
} ;
602
602
603
- // Avoid taking a server if the client just wants to disconnect.
604
- if message[ 0 ] as char == 'X' {
605
- debug ! ( "Client disconnecting" ) ;
606
- return Ok ( ( ) ) ;
607
- }
608
-
609
603
// Handle admin database queries.
610
604
if self . admin {
611
605
debug ! ( "Handling admin command" ) ;
612
606
handle_admin ( & mut self . write , message, self . client_server_map . clone ( ) ) . await ?;
613
607
continue ;
614
608
}
615
609
610
+ match message[ 0 ] as char {
611
+ // Buffer extended protocol messages even if we do not have
612
+ // a server connection yet. Hopefully, when we get the S message
613
+ // we'll be able to allocate a connection. Also, clients do not expect
614
+ // the server to respond to these messages so even if we were not able to
615
+ // allocate a connection, we wouldn't be able to send back an error message
616
+ // to the client so we buffer them and defer the decision to error out or not
617
+ // to when we get the S message
618
+ 'P' | 'B' | 'D' | 'E' => {
619
+ self . buffer . put ( & message[ ..] ) ;
620
+ continue ;
621
+ }
622
+ 'X' => {
623
+ debug ! ( "Client disconnecting" ) ;
624
+ return Ok ( ( ) ) ;
625
+ }
626
+ _ => ( ) ,
627
+ }
628
+
616
629
// Get a pool instance referenced by the most up-to-date
617
630
// pointer. This ensures we always read the latest config
618
631
// when starting a query.
@@ -714,22 +727,17 @@ where
714
727
conn
715
728
}
716
729
Err ( err) => {
717
- // Clients do not expect to get SystemError followed by ReadyForQuery in the middle
718
- // of extended protocol submission. So we will hold off on sending the actual error
719
- // message to the client until we get 'S' message
720
- match message[ 0 ] as char {
721
- 'P' | 'B' | 'E' | 'D' => ( ) ,
722
- _ => {
723
- error_response (
724
- & mut self . write ,
725
- "could not get connection from the pool" ,
726
- )
727
- . await ?;
728
- }
729
- } ;
730
-
730
+ // Client is attempting to get results from the server,
731
+ // but we were unable to grab a connection from the pool
732
+ // We'll send back an error message and clean the extended
733
+ // protocol buffer
734
+ if message[ 0 ] as char == 'S' {
735
+ error ! ( "Got Sync message but failed to get a connection from the pool" ) ;
736
+ self . buffer . clear ( ) ;
737
+ }
738
+ error_response ( & mut self . write , "could not get connection from the pool" )
739
+ . await ?;
731
740
error ! ( "Could not get connection from pool: {:?}" , err) ;
732
-
733
741
continue ;
734
742
}
735
743
} ;
0 commit comments