Skip to content

Commit 2ddc553

Browse files
committed
pg object emit error event on idle pooled client errors
1 parent d9fbe9e commit 2ddc553

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

lib/index.js

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var EventEmitter = require('events').EventEmitter;
2+
var sys = require('sys');
23
var Client = require(__dirname+'/client');
34
var defaults = require(__dirname + '/defaults');
45
var genericPool = require('generic-pool');
@@ -7,7 +8,8 @@ var genericPool = require('generic-pool');
78
var pools = {};
89

910
//returns connect function using supplied client constructor
10-
var makeConnectFunction = function(ClientConstructor) {
11+
var makeConnectFunction = function(pg) {
12+
var ClientConstructor = pg.Client;
1113
return function(config, callback) {
1214
var c = config;
1315
var cb = callback;
@@ -31,6 +33,13 @@ var makeConnectFunction = function(ClientConstructor) {
3133
};
3234
var connectSuccess = function() {
3335
client.removeListener('error', connectError);
36+
37+
//handle connected client background errors by emitting event
38+
//via the pg object and then removing errored client from the pool
39+
client.on('error', function(e) {
40+
pg.emit('error', e, client);
41+
pool.destroy(client);
42+
});
3443
callback(null, client);
3544
};
3645
client.once('connect', connectSuccess);
@@ -58,25 +67,25 @@ var end = function() {
5867
})
5968
};
6069

61-
module.exports = {
62-
Client: Client,
63-
Connection: require(__dirname + '/connection'),
64-
connect: makeConnectFunction(Client),
65-
end: end,
66-
defaults: defaults
67-
}
70+
var PG = function(clientConstructor) {
71+
EventEmitter.call(this);
72+
this.Client = clientConstructor;
73+
this.Connection = require(__dirname + '/connection');
74+
this.connect = makeConnectFunction(this);
75+
this.end = end;
76+
this.defaults = defaults;
77+
};
78+
79+
sys.inherits(PG, EventEmitter);
80+
81+
module.exports = new PG(Client);
6882

6983
var nativeExport = null;
7084
//lazy require native module...the c++ may not have been compiled
7185
module.exports.__defineGetter__("native", function() {
7286
if(nativeExport === null) {
7387
var NativeClient = require(__dirname + '/native');
74-
nativeExport = {
75-
Client: NativeClient,
76-
connect: makeConnectFunction(NativeClient),
77-
end: end,
78-
defaults: defaults
79-
}
88+
nativeExport = new PG(NativeClient);
8089
}
8190
return nativeExport;
8291
})
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
var helper = require(__dirname + "/../test-helper");
2+
var pg = require(__dirname + "/../../../lib");
3+
helper.pg = pg;
4+
5+
var conString = helper.connectionString();
6+
7+
//first make pool hold 2 clients
8+
pg.defaults.poolSize = 2;
9+
10+
var killIdleQuery = 'SELECT procpid, (SELECT pg_terminate_backend(procpid)) AS killed FROM pg_stat_activity WHERE current_query LIKE \'<IDLE>\'';
11+
12+
//get first client
13+
pg.connect(conString, assert.success(function(client) {
14+
client.id = 1;
15+
pg.connect(conString, assert.success(function(client2) {
16+
client2.id = 2;
17+
//subscribe to the pg error event
18+
assert.emits(pg, 'error', function(error, brokenClient) {
19+
assert.ok(error);
20+
assert.ok(client);
21+
assert.equal(client.id, 1);
22+
pg.end();
23+
});
24+
//kill the connection from client
25+
client2.query(killIdleQuery, assert.success(function(res) {
26+
//check to make sure client connection actually was killed
27+
assert.length(res.rows, 1);
28+
}));
29+
}));
30+
}));

0 commit comments

Comments
 (0)