2011-11-24 16 views
6

Ho una tabella "article" su un database Postgresql 9.1 e un trigger che notifica un canale su ogni inserto.LISTEN timeout della query con node-postgres?

Mi piacerebbe creare uno script node.js che catturi quegli inserti e spinga le notifiche ai client connessi usando Socket.io. Finora sto usando il modulo node-postgres su LISTEN per il canale ma sembra che la query LISTEN scade dopo circa 10-15 secondi e smette di catturare gli inserti. Potrei richiedere un nuovo ascolto quando si verifica il timeout, ma non sono sicuro di come implementare correttamente la continuazione.

Ecco la mia procedura di notifica di PostgreSQL:

CREATE FUNCTION article_insert_notify() RETURNS trigger AS $$ 
BEGIN 
    NOTIFY "article_watcher"; 
    RETURN NULL; 
END; 
$$ LANGUAGE plpgsql; 

Il trigger:

CREATE TRIGGER article_insert_trigger 
AFTER INSERT ON article 
FOR EACH ROW EXECUTE PROCEDURE article_insert_notify(); 

E il codice node.js:

var pg = require ('pg'), 
    pgConnection = "postgres://user:[email protected]/db" 

pg.connect(pgConnection, function(err, client) { 
    client.query('LISTEN "article_watcher"'); 
    client.on('notification', function(data) { 
     console.log(data.payload); 
    }); 
}); 

Come posso garantire un tempo pieno o come LISTEN posso prendere quei timeout per riemettere una query di ascolto? O forse un modulo diverso da node-postgres offre strumenti più appropriati per farlo?

+0

Usando [pg-promessa] (https://github.com/vitaly-t/pg-promise) , completi esempi con spiegazioni: [LISTEN/NOTIFY] (https://github.com/vitaly-t/pg-promise/wiki/Learn-by-Example#listen--notify) –

risposta

8

Ho ricevuto risposta al mio problema sul repository node-postgres. Per citare Brianc:

pg.connect viene utilizzato per creare connessioni in pool. L'utilizzo di una connessione per gli eventi di ascolto non è supportato o comunque una buona idea . [...] Per "ascoltare" una connessione per definizione deve rimanere aperta in modo permanente. Per una connessione per rimanere aperta in modo permanente non può mai essere restituita al pool di connessione .

Il modo corretto di ascoltare in questo caso è quello di utilizzare un client standalone: ​​

var pg = require ('pg'), 
    pgConnectionString = "postgres://user:[email protected]/db"; 

var client = new pg.Client(pgConnectionString); 
client.connect(); 
client.query('LISTEN "article_watcher"'); 
client.on('notification', function(data) { 
    console.log(data.payload); 
}); 
0

LISTEN si suppone che duri per la durata della sessione o finché non si fa UNLISTEN. Quindi, finché il codice è in esecuzione, le notifiche dovrebbero essere consegnate. Nota che IIRC, postgresql non dà promesse di consegnare una notifica per NOTIFY - se hai molti inserti, può scegliere di consegnare un singolo NOTIFY. Non sono sicuro di 9.1, hanno introdotto il carico utile LISTEN, quindi potrebbe essere un po 'meno sensato.

+0

Quindi il timeout di 15 secondi è un client problema? Posso risolvere il problema con node-postgres o sto semplicemente non avendo il buon approccio per quello che voglio fare? – lheurt

+0

Non conosco veramente la parte del nodo e non sono sicuro di aver capito appieno cosa succede con pg e questo intero ambiente dopo il codice postato ... –

Problemi correlati