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');
});