1

I am trying to allow users to export their contact list in csv format. I am confused on how to run export_connect_csv() function. should i put it in child process or process.nextTick?

function export_connect_csv(user_id, file_location){
      mysqlPool.getConnection(function(err, connection){
        var csv_row = "Email,First Name,Last Name,Status,Created\n";
        function processRow (row) {
          var csv_row = row.email+','+row.first_name+','+row.last_name+','+row.status+','+row.created+"\n";
          fs.appendFile(file_location, csv_row, function (err) {
            if(err){
              throw err;
            }
          });
        }
        fs.appendFile(file_location, csv_row, function (err) {
          if(err){
            throw err;
          }
          var query = connection.query('SELECT * FROM contacts where user_id = "'+user_id+'"');
          query
            .on('error', function(err) {
              //handle error
            })
            .on('fields', function(fields) {

            })
            .on('result', function(row) {
              processRow(row);
            })
            .on('end', function() {
              //email now

              console.log('done');
            });
        });
      });
    }

    var exportContacts = function(req, res){
      var user_id = req.params.user_id || 0;

      export_connect_csv(user_id);
      res.json({});
    };
Yalamber
  • 7,360
  • 15
  • 63
  • 89

1 Answers1

0

You don't need to use either, you can just call the function. All of that code will run assynchronously, both getConnection and fs.appendFile. However, you will run into a conflict in the case two users try to export at the same time. You have the following options:

1) You pass a unique file_name every time you call that function

2) You keep things exactly as they are and use fs.appendFileSync to make sure they don't overlap each other but that would block you

3) Or probably the best solution is do what you intended to do with the Process.nextTick, but instead you should use setImmediate and appendFileSync to be able to synchronize writes from several users simultaneously (write only a row at a time to avoid blocking for long periods):

setImmediate(function () { fs.appendFileSync('filename', JUST_A_SINGLE_ROWW) });

This is because a recursive process.nextTick can starve the event loop and effecively block you (hence the use of setImmediate) and you need to use fs.appendFileSync because two users might write to the same file simultaneously.

More on setImmediate vs nextTick: setImmediate vs. nextTick

More info on appendFile: http://nodejs.org/api/fs.html#fs_fs_appendfile_filename_data_options_callback

Community
  • 1
  • 1
Raul Martins
  • 385
  • 2
  • 6
  • So my code will not be blocking at all. it will send response to the browser and the csv file writing process will be running in background right? What would happen if there are more than 1 users exporting fiels at once? – Yalamber Jun 20 '13 at 15:54
  • Hello, thank you for the reply. File name will always be unique for each users. – Yalamber Jun 20 '13 at 17:00