Skip to content
This repository has been archived by the owner on Dec 30, 2019. It is now read-only.

Commit

Permalink
Max checkout timeout event
Browse files Browse the repository at this point in the history
Emit a `maxCheckoutExceeded` event when a connection has been checked
out longer then the user defined `maxCheckoutMillis` timeout.
  • Loading branch information
johanneswuerbach committed Dec 16, 2018
1 parent 35a285c commit 8174166
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 4 deletions.
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var pool2 = new Pool({
min: 4, // set min pool size to 4
idleTimeoutMillis: 1000, // close idle clients after 1 second
connectionTimeoutMillis: 1000, // return an error after 1 second if connection could not be established
maxCheckoutMillis: 1000 // receive a maxCheckoutExceeded event after 1 second
})

//you can supply a custom client constructor
Expand Down Expand Up @@ -79,7 +80,7 @@ const pool = new Pool(config);
ssl: true
}
*/
```
```

### acquire clients with a promise

Expand Down Expand Up @@ -296,6 +297,30 @@ setTimeout(function () {

```

#### maxCheckoutExceeded

Fired whenever a client is checked out longer then `maxCheckoutMillis`

Example:

This allows you to count the number of clients which have exceeded the checkout timeout.

```js
var Pool = require('pg-pool')
var pool = new Pool({ maxCheckoutMillis : 1000 })

let checkoutExceededCount = 0

pool.on('maxCheckoutExceeded', function (client) {
checkoutExceededCount++;
})

setTimeout(function () {
console.log('checkout exceeded count:', checkoutExceededCount) // output: checkout exceeded count: 1
}, 1500)

```

### environment variables

pg-pool & node-postgres support some of the same environment variables as `psql` supports. The most common are:
Expand Down
23 changes: 20 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ class Pool extends EventEmitter {
const client = idleItem.client
client.release = release.bind(this, client)
this.emit('acquire', client)
return waiter.callback(undefined, client, client.release)

return this._callCallback(client, waiter.callback)
}
if (!this._isFull()) {
return this.newClient(waiter)
Expand All @@ -148,6 +149,20 @@ class Pool extends EventEmitter {
this.emit('remove', client)
}

_callCallback (client, callback) {
if (!this.options.maxCheckoutMillis) {
return callback(undefined, client, client.release)
}

const tid = setTimeout(() => {
this.emit('maxCheckoutExceeded', client)
}, this.options.maxCheckoutMillis)
return callback(undefined, client, (err) => {
clearTimeout(tid)
client.release(err)
})
}

connect (cb) {
if (this.ending) {
const err = new Error('Cannot use a pool after calling end on the pool')
Expand Down Expand Up @@ -250,9 +265,11 @@ class Pool extends EventEmitter {
this.emit('acquire', client)
if (!pendingItem.timedOut) {
if (this.options.verify) {
this.options.verify(client, pendingItem.callback)
this._callCallback(client, (_, client) => {
this.options.verify(client, pendingItem.callback)
})
} else {
pendingItem.callback(undefined, client, client.release)
this._callCallback(client, pendingItem.callback)
}
} else {
if (this.options.verify) {
Expand Down
59 changes: 59 additions & 0 deletions test/connection-timeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,63 @@ describe('connection timeout', () => {
})
})
})

it('emits a maxCheckoutExceeded event on new connections', (done) => {
const pool = new Pool({
maxCheckoutMillis: 1000,
max: 1
})

let maxCheckoutExceededCount = 0

pool.on('maxCheckoutExceeded', () => {
maxCheckoutExceededCount++
})

// First connect with a slow checkout
pool.connect((err, client, release) => {
expect(err).to.be(undefined)

client.query('select pg_sleep(2)', (err) => {
expect(err).not.to.be.ok()

release()
expect(maxCheckoutExceededCount).to.be(1)
pool.end(done)
})
})
})

it('emits a maxCheckoutExceeded event on queued connections', (done) => {
const pool = new Pool({
maxCheckoutMillis: 1000,
max: 1
})

let maxCheckoutExceededCount = 0

pool.on('maxCheckoutExceeded', () => {
maxCheckoutExceededCount++
})

// First connect with a fast checkout
pool.connect((err, client, release) => {
expect(err).to.be(undefined)

// Slow checkout queued afterwards
pool.connect((err, client, release) => {
expect(err).to.be(undefined)

client.query('select pg_sleep(2)', (err) => {
expect(err).not.to.be.ok()

release()
expect(maxCheckoutExceededCount).to.be(1)
pool.end(done)
})
})

release()
})
})
})

0 comments on commit 8174166

Please sign in to comment.