The way Native Bindings currently work, is by overriding the library's global settings:
module.exports.__defineGetter__("native", function () {
delete module.exports.native;
module.exports.native = new PG(require('./native'));
return module.exports.native;
});
As a result, it creates a conflict when you try using two third-party libraries -
pg via Native Bindingspg via JavaScript bindingsJust as one library activates Native Bindings, it becomes global, due to Node.js module sharing principle, so it overrides this setting for libraries that do not support Native Bindings.
Install pg-native, and declare:
var pg1 = require('pg');
var pg2 = require('pg').native;
Just as pg2 is initialized, any call into pg1 for connect or query goes into the layer for the Native Bindings, thus breaking any module that supports only JavaScript bindings.
I don't know yet how difficult it would be to fix this, or even whether it is possible to make Native Bindings work in parallel with JavaScript Bindings within the same process, without running into conflicts. Any thoughts are welcome!
Below is a complete example showing the issue:
var pg1 = require('pg');
//var pg2 = require('pg').native;
var cn = "pg://postgres@localhost:5000/test"; // invalid connection
pg1.connect(cn, function (err) {
return console.error(err);
});
it outputs connection error from JavaScript bindings:
{ [Error: connect ECONNREFUSED 127.0.0.1:5000]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 5000 }
Now let's un-comment that second require:
var pg1 = require('pg');
var pg2 = require('pg').native;
var cn = "pg://postgres@localhost:5000/test"; // invalid connection
pg1.connect(cn, function (err) {
return console.error(err);
});
Now suddenly the error arrives formatted according to the Native Bindings:
error fetching client from pool { [Error: connect ECONNREFUSED 127.0.0.1:5430]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 5430 }
even though we are still using pg1, i.e. the second require overrides global binding settings, so we no longer have access to the JavaScript bindings of the library. This will break any library that tightly relies on JavaScript bindings.
@brianc do you think this is something that is doable?
I would try and do a PR for this, though I'm not sure if it will work. From your perspective, as the insider, is it possible to isolate the two things from each other, and use them in parallel?
Offf yeah that's just a nasty bug. I'm putting together a PR for it right now. 鉂わ笍
@brianc Fantastic!!! Much appreciated!!!
Fixed in version 4.5.3.
My testing confirms that it is working now, at least on the surface - connections are now correct. It would take running the two bindings side-by-side to see if there is any issue remains. Time will tell ;)
@brianc Thank you!
Most helpful comment
Offf yeah that's just a nasty bug. I'm putting together a PR for it right now. 鉂わ笍