New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Client side socket timeout (not statement_timeout) #3124
Comments
My Azure App Service is doing the same thing. |
@Safricloud Encountered this on azure too, when using a virtual network gateway. I ended up upgrading it, and it stopped dropping the connections |
I can't run that command ( Reproducing a connection that hangs specifically during a call to the Another useful setting to keep in mind during these situations (though it wouldn't have helped here specifically) is setting |
You are correct, I had this issue both while creating a new connection, And when waiting for a response on a query. import socket
import sys
import threading
import time
import select
PROXY_PORT = 54321
POSTGRES_PORT = 5432
POSTGRES_HOST = 'localhost'
HALT_PROXY_KEY = 'q'
HALT_PROXY_TRANSFER_KEY = 'w'
def main():
proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
proxy_socket.bind(('', PROXY_PORT))
proxy_socket.listen(10)
print(f"Press {HALT_PROXY_KEY} to halt proxy, {HALT_PROXY_TRANSFER_KEY} to halt transfer")
try:
while True:
client_socket, addr = proxy_socket.accept()
print('Got a connection from %s' % str(addr))
thread = threading.Thread(target=handle_request, args=(client_socket,))
thread.start()
except:
proxy_socket.close()
def handle_request(client_socket):
postgres_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
postgres_socket.connect((POSTGRES_HOST, POSTGRES_PORT))
postgres_socket.settimeout(1)
sockets = [client_socket, postgres_socket]
stop_transfer = False
while True:
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
key = sys.stdin.read(1)
if key == HALT_PROXY_KEY:
break
elif key == HALT_PROXY_TRANSFER_KEY:
stop_transfer = True
try:
read_sockets, write_sockets, error_sockets = select.select(sockets, [], [])
for sock in read_sockets:
if sock == client_socket:
data = client_socket.recv(1024)
if not data:
break
print('> Packet from client')
if not stop_transfer:
postgres_socket.sendall(data)
elif sock == postgres_socket:
data = postgres_socket.recv(1024)
if not data:
break
print('< Packet from postgres')
if not stop_transfer:
client_socket.sendall(data)
except socket.timeout:
print('timeout')
pass
except socket.error:
print('error')
break
client_socket.close()
postgres_socket.close()
if __name__ == '__main__':
main()
Can't remember exactly now why I decided it didn't work. I might try to get back to replicating this issue later this week with the proxy. |
Yep, I started your script, connected from client.jsimport pg from 'pg'
const { Client } = pg;
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
}
async function main() {
const client = new Client({
connectionString: "postgresql://localhost:54321",
// This ///////////////////////////////////////////////////////////////
query_timeout: 3000,
///////////////////////////////////////////////////////////////////////
})
await client.connect();
for (let i = 0; i < 60; i++) {
const result = await client.query('select current_timestamp ct;');
console.log(result.rows[0].ct);
await sleep(1000);
}
await client.end();
}
main();
Hope this helps. |
Not sure where my tests went wrong earlier. Ill check it out again. |
I was able to solve my problem by setting this in pool connection options:
This threshold is the same as what Azure is using on their proxy to timeout connections, so now my app just reconnects when needed and never assumes that a connection is alive when its not. |
@Safricloud If I am not mistaken, this will only fix the problem for idle connections, not for connections that are waiting for a response from the db. |
For active queries you can set a timeout with this pool/connection option: I was using this getWorkingConnection function to verify my results:
|
Hi, I'm wondering if there is an option to set a client side query timeout for a pool.
I have a network issue, where the socket stays open, but is no longer connected to postgres (im using some sort of proxy).
This can be replicated by a simple
nc -nvlp 5432
.I am aware of
statement_timeout
, but this is a server side timeout which will not work in my case.Ideally, I would like an option like
socket_read_timeout
, that will throw an error.Thanks!
The text was updated successfully, but these errors were encountered: