2016-02-04 17 views
5

Sul mio server, ogni volta che un utente usa il nostro servizio dobbiamo prendere un file JSON dal server. Lo faccio utilizzando fs.createReadStream() all'interno della mia funzione.Node.js non chiude i file creati da fs.createReadStream()

function getJSONFromServer(filepath, callback){ 
    var data = fs.createReadStream(filepath); 
    data.on('error', function (error) { 
     console.log("Caught", error); 
     callback(undefined, error); 
    }); 
    var jsonFile = ""; 
    data.on('data', function(chunk) { 
     jsonFile += chunk; 
    }); 
    data.on('end', function() { 
     var jsonData = JSON.parse(jsonFile); 
     callback(jsonData); 
     data.destroy(); 
     data.close(); 
    }); 
} 

Questo fa il lavoro, ma non chiude la connessione al file. Quindi dopo aver letto 1024 file (il limite sul mio server), Node.js produrrà quindi l'errore EMFILE, too many open files. Quindi devo uccidere il nostro server Node.js, aprirlo di nuovo e questo cancellerà i "file aperti".

Controllo la quantità di file aperti da lsof -i -n -P | grep nodejs. Viene visualizzato qualcosa del genere:

nodejs 13707  node 10u IPv4 1163695  0t0 TCP 127.0.0.1:55643->127.0.0.1:27017 (ESTABLISHED) 
nodejs 13707  node 11u IPv4 1163697  0t0 TCP 127.0.0.1:55644->127.0.0.1:27017 (ESTABLISHED) 

per quanti file sono aperti.

Ho provato a usare graceful-fs. Ho provato a chiamare stream.destroy() e stream.close(), ma ho ancora lo stesso problema. Il mio server è essenzialmente una bomba a orologeria, perché otteniamo un flusso di utenti pesante e costante e, dopo che molti utenti l'hanno collegato, smetterà di funzionare.

Inoltre, ulimit -n [open file amount] non funziona, e anche se così fosse, questa non è una soluzione a lungo termine, perché mi piacerebbe che le mie connessioni di file si chiudessero e non rimanessero aperte senza motivo.

Sto usando la versione Node.js v0.10.25, Ubuntu 15.04 (GNU/Linux 3.19.0-42-generic x86_64) e l'ultima versione di graceful-fs se questo aiuta!

Grazie per l'aiuto che puoi fornire.

+0

Potrebbe suggerirti di utilizzare ['fs.readFile()'] (https://nodejs.org/api/fs.html#fs_fs_readfile_file_options_callback) che eseguirà automaticamente l'intera stringa che si aggiunge a te e gestisce anche correttamente tutti gli errori condizioni? Forse questa non era un'opzione quando hai posto la domanda, ma ti farà risparmiare molte righe qui ;-). – binki

risposta

3

Questo deve essere l'errore più stupido che abbia mai fatto. Indipendentemente da ciò, ecco la risposta. Spero di poter salvare qualcuno dall'affrontare questo errore e quasi strappargli i capelli.

Ho eseguito la mia app con nodejs e non node. Risulta, se lo fai nodejs --version, probabilmente restituirà una versione che è molto vecchia, che era v0.10.25 per me. node --version tuttavia era v5.6.0. Ovviamente questo gigantesco salto nelle versioni risolverebbe alcune cose, quindi ho eseguito l'app con node app.js invece di nodejs app.js e da allora non ho più avuto il problema. Ora ci sono solo 6 file aperti, mentre prima avevamo più di 1000 con il tempo.

Accidenti, è bello averlo fuori dal mio petto.