I'm running a simple test against the latest pg, under Node.js 8.1.2:
const pg = require('pg');
var client = new pg.Client(connection);
function test() {
client.connect(err => {
if (err) {
console.log(err);
return;
}
client.query('select 123', [], (err, data) => {
if (err) {
console.log(err);
} else {
console.log('DATA:', data.rows[0]);
}
client.end();
});
});
}
setInterval(test, 1000);
And it outputs the following, every time:
DATA: anonymous { '?column?': 123 }
DATA: undefined
DATA: undefined
DATA: undefined
DATA: undefined
DATA: undefined
DATA: undefined
DATA: undefined
events.js:182
throw er; // Unhandled 'error' event
^
error: invalid frontend message type 0
at Connection.parseE (D:\NodeJS\tests\node_modules\pg\lib\connection.js:567:11)
at Connection.parseMessage (D:\NodeJS\tests\node_modules\pg\lib\connection.js:391:17)
at Socket.<anonymous> (D:\NodeJS\tests\node_modules\pg\lib\connection.js:129:22)
at emitOne (events.js:120:20)
at Socket.emit (events.js:210:7)
at addChunk (_stream_readable.js:252:12)
at readableAddChunk (_stream_readable.js:239:11)
at Socket.Readable.push (_stream_readable.js:197:10)
at TCP.onread (net.js:588:20)
After I successfully call client.end(), it will successfully re-connect, successfully execute the query, just won't return any data. This looks odd.
And this - error: invalid frontend message type 0 doesn't make any sense.
Could somebody, please explain, why we get such an odd output?
UPDATE
And if just after creating the client, I add the following:
client.on('error', e => {
console.log(e);
});
The output gets absolutely flooded with a huge error dumb, so big, I can't even paste it here.
I’m almost certain clients aren’t meant to be connected more than once (@brianc, could you confirm this?); treat them as unusable after calling .end().
- var client = new pg.Client(connection);
-
function test() {
+ var client = new pg.Client(connection);
+
client.connect(err => {
if (err) {
console.log(err);
return;
}
client.query('select 123', [], (err, data) => {
if (err) {
console.log(err);
} else {
console.log('DATA:', data.rows[0]);
}
client.end();
});
});
}
I’m almost certain clients aren’t meant to be connected more than once...
And what is the reason for that?
They’re wrappers around a connection and should be associated with one connection.
Yeah though it's not really documented clients are cheap to instantiate and should be considered 'used up' once they've been disconnected. There's a bit of a state machine inside the client w/ a bunch of event handlers being established after the connect event. Your best bet is going to be to throw the old one away & make a new one. The connection handshake over tcp is the part that takes a little bit of time, but reusing an existing client wouldn't save any time there as reconnecting would still need to happen - it would also introduce additional complexity in ensuring the old event handlers were disposed and the new ones set up correctly. I'll re-open this & add it to the 7.0 milestone to return an error if a client has connect called on it more than once - hopefully that will make things more clear.
It would be nice! The Client should throw an error when someone is trying to reconnect or call .query after calling .end(), the same as pg-pool should be throwing an error when someone calls .connect or .query after pool.end() has been called.
Closed with #1365
I have a similar problem.
`const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {
console.log('after connect');
client.connect();
client.query("SELECT FROM users where id = $1", [payload.sub], function(err, data) {
if (err) { return done(err, false); }
if (data) {
console.log('inside data');
client.end((err) => {
console.log('client has been disconnected');
if (err) {
console.log('there has been error disconnecting from client: ', err);
}
});
return done(null, data);
} else {
console.log('hereeeeeeeeeeeeee?');
client.end();
return done(null, false);
}
});
});`
The first time I hit my endpoint that runs this code, everything works fine. I get my data back from the database fetch and it console.logged "client has been disconnected" but when I hit this endpoint again, my code only console.log('after connect') and none of my other code runs. I get
Unhandled promise rejection (rejection id: 1): Error: Client has already been connected. You cannot reuse a client.
Am I using client.end() incorrectly?
@waruwaruwaru Don’t end the client if you want to continue using it. If you want to create a new client each time instead of keeping one open, you’ll have to do just that (client = new Client(…); client.connect(…) in function (payload, done)). If you want a connection pool (this is the usual case), use Pool instead.
@charmander Thank you.
Someone might get misunderstood the comment above, therefore I shall note:
1) Create a new client each time is slow
2) Keep one open client is unreliable
3) Use a Pool is the right way (https://node-postgres.com/features/pooling)
Most helpful comment
I’m almost certain clients aren’t meant to be connected more than once (@brianc, could you confirm this?); treat them as unusable after calling
.end().