I ran into a problem where a service caused a deadlock by waiting on getConnection. Here is a rough example of the code:
await pool.withTransaction(async tx => {
await service.prepare()
await doSomething(tx)
})
Many long-running requests caused the pool to saturate, then the service caused a deadlock and kept the transaction open. This is easily fixed by not giving service the pool, or by checking that we aren't already in a transaction.
However, a timeout could be useful to avoid these unexpected situations:
// 5s timeout on getConnection
const pool = createPool({ acquireTimeout: 5_000 });
// and/or
await pool.getConnection({ timeout: 1_000 })
// or with signals
await pool.getConnection({ signal: AbortSignal.timeout(1_000) })
A timeout can be implemented by users, but they can't remove the request from the queue on timeout. There is also a gotcha that leaks connections if not implemented correctly. So, I think this should be a library feature.
I ran into a problem where a service caused a deadlock by waiting on
getConnection. Here is a rough example of the code:Many long-running requests caused the pool to saturate, then the service caused a deadlock and kept the transaction open. This is easily fixed by not giving
servicethe pool, or by checking that we aren't already in a transaction.However, a timeout could be useful to avoid these unexpected situations:
A timeout can be implemented by users, but they can't remove the request from the queue on timeout. There is also a gotcha that leaks connections if not implemented correctly. So, I think this should be a library feature.