pgsql icon indicating copy to clipboard operation
pgsql copied to clipboard

Added a connection_timeout option and the related test case

Open benjamin-bergia opened this issue 7 years ago • 8 comments

Related to https://github.com/semiocast/pgsql/issues/49. I don't know if the lists:keytake/3 is necessary here might rewrite it with a lists:keyfind/3 instead.

benjamin-bergia avatar Jul 10 '18 02:07 benjamin-bergia

When you call gen_server:start_link and hit a timeout, does the server get cleaned up properly? Like, if you hit the timeout because you're waiting in line for PG, does the connection drop, or does Postgres see a client until it reaches TCP timeout?

waisbrot avatar Jul 10 '18 02:07 waisbrot

I will see if I can find a way to test this. The current test case is only there to test that the option is valid. I noticed that depending at which point in the initialization process the timeout append, postgres may throw an "incomplete startup packet" error.

I have been inserting timer:sleep/1 at different stages of the connection to trigger the timeout, but it is not very reliable. Do you have any suggestion?

benjamin-bergia avatar Jul 10 '18 06:07 benjamin-bergia

Yeah, it seems like too much bother to make an automated test for it. I'm just not familiar enough with the inner details of gen_server to know exactly what happens in this case. But it seems relevant to your use-case, because if PG is overloaded this could just make it more overloaded. (Though it seems promising that in your own case making this change worked out well.)

waisbrot avatar Jul 10 '18 11:07 waisbrot

@waisbrot Sorry haven't had time to work on this. Can I keep the PR open and I update it once I get an answer to your question?

benjamin-bergia avatar Jul 18 '18 02:07 benjamin-bergia

I don't have merge powers. Just fond of this library and hoping it's helpful if I review a bit.

@pguyot seems at least somewhat active, but this is a pretty quiet repository so I doubt it's a big deal to leave it open. Especially when you're so diligent that you check in every couple weeks!

waisbrot avatar Jul 18 '18 02:07 waisbrot

I understand the issue is that the supervisor's mailbox is full because opening connections takes too much time. Adding a timeout on start_link will not fully fix the problem: each pgsql_connection process that fails to open a connection within the allocated timeout will nevertheless stress the server (and the local operating system) and potentially slow down the next processes.

What do you think about moving the open logic out of init/1 handler and open the connection asynchronously by self-sending a specific 'open' message? The supervisor will be able to handle as many new children as needed (init/1 currently doesn't do much except opening the connection). A connection timeout option seems to be a different feature and is compatible with this approach. Also, such an option probably should be applied to both the first connection and reconnections if reconnect option is also provided.

pguyot avatar Jul 18 '18 06:07 pguyot

@pguyot Sounds good to me. As I mentioned above, I might not be able to start right way but if nobody else has an immediate need for this fix I would be interested to work on it.

benjamin-bergia avatar Jul 18 '18 06:07 benjamin-bergia

I did some modifications already and I am wondering if I should keep the timeout where it is or move it down to the tcp:connect/3 in pgsql_open/1. It would automatically apply to connections and reconnections. But in an other hand I am afraid that, in some cases, the connection hang higher up, during the communication with postgres not when the tcp connection is being established.

benjamin-bergia avatar Jul 26 '18 03:07 benjamin-bergia