Closed JaredBoone closed 6 years ago
I have worked around this by wrapping the SQL in trigger.sql.tpl in a transaction that includes a transaction-level advisory lock as follows:
BEGIN;
SELECT pg_advisory_xact_lock(510127006994284723); --64 bit unsigned int
CREATE OR REPLACE FUNCTION ...
$$ LANGUAGE plpgsql;
COMMIT;
See https://stackoverflow.com/questions/40525684/tuple-concurrently-updated-when-creating-functions-in-postgresql-pl-pgsql for more details.
In case anyone else runs into this, the package owner informed me that the channel string must be unique for each child process. Here's an example of how to do this:
parent.js:
const { fork } = require('child_process');
const numForks = 2;
for (var i = 0; i < numForks; i++) {
var child = fork(require.resolve('./child.js'), [], { env: {
CONN: 'postgres://meteor:meteor@127.0.0.1/meteor',
CHANNEL: 'chan_'+i } });
}
child.js:
const LivePG = require('pg-live-select');
var liveDb;
process.on('exit', () => {
if (liveDb) {
liveDb.cleanup(() => console.log('cleaned up'));
}
});
liveDb = new LivePG(process.env.CONN, process.env.CHANNEL)
liveDb.select('SELECT * FROM assignments')
.on('update', function (diff, data) {
console.log(process.env.CHANNEL + ': ', data);
});
If you run pg-live-select in multiple processes concurrently, postgres throws "ERROR: tuple concurrently updated". This happens because CREATE FUNCTION (from triggers.sql.tpl) can't be used concurrently.