andy0130tw
3/26/2016 - 4:37 PM

Learn Mode mood bulk backup, demostrating network/disk IO performance optimization in async nature on Node.js

Learn Mode mood bulk backup, demostrating network/disk IO performance optimization in async nature on Node.js

#!/usr/env/bin node

var fs = require('fs');

var request = require('request');
var async = require('async');
var sqlite3 = require('sqlite3');

var db = new sqlite3.Database('learnmode.sqlite');
var url = 'https://message.learnmode.net:5443/api/mood/list?count=3000&device=--:--:--:--:--:--&id=';  /* fill in an MAC address */

var CONCURRENCY = 10;
var RECORDS_PER_COMMIT = 20;

var moodList = fs.readFileSync('mood_id_list', 'utf-8').split('\n');

function elapsedTime(prevTimer, diffTimer) {
    var diff = diffTimer ? [diffTimer[0] - prevTimer[0], diffTimer[1] - prevTimer[1]] : process.hrtime(prevTimer);
    return diff[0] * 1e3 + Math.floor(diff[1] / 1e6);
}

var session = request.defaults({
    pool: {maxSockets: 4},
    gzip: true,
    json: true,
    forever: true
});

var runCnt = 0;

async.forEachOfLimit(moodList, CONCURRENCY, function(id, i, cb_nextItem) {
    if (!id) return cb_nextItem();

    console.log(id, Math.floor((i+1) / moodList.length*100) + '%');
    var timerReq = process.hrtime();

    session.get(url + id, function(err, resp) {
        var timerDB = process.hrtime();

        var list = resp.body.list;
        db.serialize(function() {
            if (runCnt % RECORDS_PER_COMMIT == 0)
                db.run('BEGIN TRANSACTION');

            var stmt = db.prepare('INSERT INTO mood (id, mood, user, date) VALUES(?, ?, ?, ?)');
            list.forEach(function(v) {
                stmt.run(id, v.mood, v.user, v.date);
            });

            if ((runCnt + 1) % RECORDS_PER_COMMIT == 0)
                db.run('COMMIT');
            runCnt++;
        });

        console.log(
            '#' + i,
            id,
            'len=' + list.length,
            '(' + elapsedTime(timerReq, timerDB) + ', ' + elapsedTime(timerDB) + 'ms)');

        cb_nextItem();
    });
}, function(err) {
    if (err) throw err;
    console.log('Success');
});