2012-06-03 13 views
8

Il mio script node.js legge righe da una tabella nel database 1, fa un po 'di elaborazione e scrive le righe del database 2.cosa è un buon modo per uscire da uno script node.js dopo "tutto è stato fatto"

Lo script dovrebbe uscire dopo che è stato fatto tutto.

Come posso sapere se è stato eseguito tutto e uscire dal nodo?

Se ho una funzione di callback come questo:

function exit_node() { 
    process.exit(); 
} 

(Edit: nel frattempo è diventato evidente che process.exit() potrebbe essere anche sostituita con db.Close() - ma questo non è la domanda su cosa mettere lì. La domanda è in che momento esattamente per fare questo, cioè come e dove eseguire questa richiamata.)

Ma non è facile da allegare da qualche parte. Dopo l'ultima lettura da db1 non è corretto, perché l'elaborazione e la scrittura devono ancora avvenire.

Allegarlo alla scrittura su db2 non è facile, perché deve essere allegato dopo l'ultima scrittura, ma ogni scrittura è indipendente e non sa se è l'ultima scrittura.

In teoria potrebbe anche succedere che l'ultima scrittura sia terminata, ma un'altra scrittura prima ancora in esecuzione.


Edit: Scusa, posso vedere la spiegazione della questione non è completa e probabilmente confusa, ma alcune persone ancora capito e ci sono buone risposte qui sotto. Per favore continua a leggere i commenti e le risposte e dovrebbe darti l'intera immagine.


Modifica: Potrei pensare a qualche meccanismo di "blocco" del controller. Le diverse parti dello script aggiungono blocchi al controllore per ogni "lavoro" aperto e le rilasciano dopo che il lavoro è finito, e il controllore esce dallo script quando non sono presenti più bocker. Forse async potrebbe aiutare: https://github.com/caolan/async

Ho anche paura che questo potrebbe far esplodere il codice e la logica irragionevole.

+0

Non capisco la tua domanda. Il nodo * fa * l'uscita quando tutto è fatto. Una volta che non ci sono più chiamate asincrone in corso, una volta che hai finito di elaborare l'ultimo record che hai letto e tutte le tue scritture sono state completate, il nodo uscirà da solo; non devi fare niente di speciale. –

+6

@JoeWhite Molti moduli di database terranno aperta una connessione, mantenendo il processo in esecuzione. Penso che la domanda (correggimi se sbaglio, SHernandez) è come sapere quando il nodo ha terminato con tutti gli IO asincroni relativi ai database, in modo che possa sapere quando chiudere la connessione DB permettendo al processo di uscire. –

+2

Il nodo non si chiude finché non ci sono uno o più callback in attesa o gli emettitori di eventi attivi. Come menzionato @BrandonTilley, alcuni dei moduli DB mantengono aperta la connessione DB (che è EventEmitter), quindi dovresti chiuderla dopo aver terminato le tue query. Quindi nel callback della query scrive qualcosa come 'db.close' (vedi i documenti), i risultati del processo e il nodo usciranno da soli (senza che tu chiami' process.exit'). – elmigranto

risposta

3

pur usando contatore potrebbe essere tentati (semplice, idea facilmente implementabile), sarà inquinare il codice con la logica non correlato.

db1.query(selector, function(err, results) { 
    db1.close(); 

    // let's suppose callback gets array of results; 
    // once all writes are finished, `db2.close` will be called by async 
    async.forEach(results, processRow, db2.close); 
}); 

// async iterator 
function processRow(row, cb) { 
    // modify row somehow 
    var newRow = foo(row); 

    // insert it in another db; 
    // once write is done, call `cb` to notify async 
    db2.insert(newRow, cb); 
} 

Anche se, utilizzando process.exit qui si sente come C++ new senza delete per me. Cattivo confronto forse, ma non può aiutarlo :)

+0

Cosa significa selettore? (Primo parametro di db1.query)? – SHernandez

+0

@SHernandez Si ** selezionare ** righe in qualche modo, giusto? Se è Postgres, 'selector' sarebbe una stringa (' SELECT now(); 'qualcosa). Se è un altro DB, il selettore sarebbe qualcos'altro. La stessa cosa con 'newRow' in fase di inserimento. Ad ogni modo, questa era un'idea nella mia risposta, non un vero codice. – elmigranto

7

Le due opzioni principali sono:

  1. utilizzare un modulo coordinamento elaborazione asincrona come async (come lei ha ricordato).
  2. mantenere il proprio numero di scritture in sospeso e poi uscire quando il conteggio conteggio raggiunge 0.
+0

Mi piace no 2. Non dovrebbe essere un problema aumentare e diminuire lo stesso contatore globale da diverse routine di callback in parallelo? L'aumento e la diminuzione possono verificarsi in qualsiasi momento da diverse parti dell'applicazione, posso farlo nel nodo? – SHernandez

+0

Non c'è alcun problema con il conflitto mentre l'elaborazione è asincrona, è ancora single threaded. – JohnnyHK

+0

@SHernandez nulla nel nodo stesso è parallelo. Non ci sono due righe di codice nel tuo intero progetto, che potrebbero essere eseguite nello stesso momento. Quindi, non è necessario in serializzazione di accesso. – elmigranto

10

JohnnyHK dà buoni consigli; ad eccezione di Node.js già fa l'opzione 2 per te.

Quando non ci sono più i/o, timer, intervalli, ecc. (Non ci si aspetta altro lavoro), il processo uscirà.Se il tuo programma non si chiude automaticamente dopo che tutto il suo lavoro è terminato, allora hai un bug. Forse hai dimenticato di chiudere una connessione DB, oppure a clearTimeout() o clearInterval(). Ma invece di chiamare process.exit() potresti cogliere questa opportunità per identificare la tua perdita.

+0

JasonSmith, è il contrario, ho cercato di spiegare nella domanda. Perché io uso callback nessuno di loro sa quale sia l'ultimo. E non appena lo so, quando tutto è fatto, posso chiudere la connessione db o uscire o qualsiasi altra cosa. Ma questo era il motivo della mia domanda, in primo luogo. – SHernandez

+2

questo è :), grazie, 'Se il tuo programma non esce automaticamente dopo che tutto il suo lavoro è terminato, allora hai un bug ' – Rabea

Problemi correlati