checkAllPads: Increase performance/resilience

Performance: Don't preload pads. Check for pool only once per pad.
Resilience: Handle missing revision.
This commit is contained in:
Claas Augner 2018-03-09 14:02:22 +01:00 committed by GitHub
parent 5c864ec47d
commit 5c915062e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 79 additions and 72 deletions

View File

@ -1,5 +1,5 @@
/* /*
This is a debug tool. It checks all revisions of all pads for data corruption This is a debug tool. It checks all revisions for data corruption
*/ */
if(process.argv.length != 2) if(process.argv.length != 2)
@ -35,96 +35,103 @@ async.series([
padManager.listAllPads(function(err, res) padManager.listAllPads(function(err, res)
{ {
var padIds = res.padIDs; padIds = res.padIDs;
pads = []; callback(err);
async.forEach(padIds, function(padId, callback) {
padManager.getPad(padId, function(err, pad) {
pads.push(pad);
callback(err);
})
}, callback);
}); });
}, },
function (callback) function (callback)
{ {
async.forEach(pads, function(pad, callback) async.forEach(padIds, function(padId, callback)
{ {
//create an array with key kevisions padManager.getPad(padId, function(err, pad) {
//key revisions always save the full pad atext if (err) {
var head = pad.getHeadRevisionNumber(); callback(err);
var keyRevisions = []; }
for(var i=0;i<head;i+=100)
{ //check if the pad has a pool
keyRevisions.push(i); if(pad.pool === undefined )
}
//run trough all key revisions
async.forEachSeries(keyRevisions, function(keyRev, callback)
{
//create an array of revisions we need till the next keyRevision or the End
var revisionsNeeded = [];
for(var i=keyRev;i<=keyRev+100 && i<=head; i++)
{ {
revisionsNeeded.push(i); console.error("[" + pad.id + "] Missing attribute pool");
callback();
return;
}
//create an array with key kevisions
//key revisions always save the full pad atext
var head = pad.getHeadRevisionNumber();
var keyRevisions = [];
for(var i=0;i<head;i+=100)
{
keyRevisions.push(i);
} }
//this array will hold all revision changesets //run trough all key revisions
var revisions = []; async.forEachSeries(keyRevisions, function(keyRev, callback)
//run trough all needed revisions and get them from the database
async.forEach(revisionsNeeded, function(revNum, callback)
{ {
db.db.get("pad:"+pad.id+":revs:" + revNum, function(err, revision) //create an array of revisions we need till the next keyRevision or the End
var revisionsNeeded = [];
for(var i=keyRev;i<=keyRev+100 && i<=head; i++)
{ {
revisions[revNum] = revision; revisionsNeeded.push(i);
callback(err);
});
}, function(err)
{
if(err)
{
callback(err);
return;
} }
//check if the pad has a pool //this array will hold all revision changesets
if(pad.pool === undefined ) var revisions = [];
{
console.error("[" + pad.id + "] Attribute pool is missing");
callback();
return;
}
//check if there is a atext in the keyRevisions //run trough all needed revisions and get them from the database
if(revisions[keyRev] == null || revisions[keyRev].meta === undefined || revisions[keyRev].meta.atext === undefined) async.forEach(revisionsNeeded, function(revNum, callback)
{ {
console.error("[" + pad.id + "] No atext in key revision " + keyRev); db.db.get("pad:"+pad.id+":revs:" + revNum, function(err, revision)
callback();
return;
}
var apool = pad.pool;
var atext = revisions[keyRev].meta.atext;
for(var i=keyRev+1;i<=keyRev+100 && i<=head; i++)
{
try
{ {
//console.log("check revision " + i); revisions[revNum] = revision;
var cs = revisions[i].changeset; callback(err);
atext = Changeset.applyToAText(cs, atext, apool); });
}, function(err)
{
if(err)
{
callback(err);
return;
} }
catch(e)
{ //check if the revision exists
console.error("[" + pad.id + "] Bad changeset at revision " + i + " - " + e.message); if (revisions[keyRev] == null) {
console.error("[" + pad.id + "] Missing revision " + keyRev);
callback(); callback();
return; return;
} }
}
//check if there is a atext in the keyRevisions
callback(); if(revisions[keyRev].meta === undefined || revisions[keyRev].meta.atext === undefined)
}); {
}, callback); console.error("[" + pad.id + "] Missing atext in revision " + keyRev);
callback();
return;
}
var apool = pad.pool;
var atext = revisions[keyRev].meta.atext;
for(var i=keyRev+1;i<=keyRev+100 && i<=head; i++)
{
try
{
//console.log("[" + pad.id + "] check revision " + i);
var cs = revisions[i].changeset;
atext = Changeset.applyToAText(cs, atext, apool);
}
catch(e)
{
console.error("[" + pad.id + "] Bad changeset at revision " + i + " - " + e.message);
callback();
return;
}
}
callback();
});
}, callback);
});
}, callback); }, callback);
} }
], function (err) ], function (err)