|
|
@ -32,6 +32,26 @@ Env = {
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = function (Env, cb) {
|
|
|
|
module.exports = function (Env, cb) {
|
|
|
|
var complete = Util.once(Util.mkAsync(cb));
|
|
|
|
var complete = Util.once(Util.mkAsync(cb));
|
|
|
|
|
|
|
|
var report = {
|
|
|
|
|
|
|
|
// archivedChannelsRemoved,
|
|
|
|
|
|
|
|
// archivedAccountsRemoved,
|
|
|
|
|
|
|
|
// archivedBlobProofsRemoved,
|
|
|
|
|
|
|
|
// archivedBlobsRemoved,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// totalChannels,
|
|
|
|
|
|
|
|
// activeChannels,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// totalBlobs,
|
|
|
|
|
|
|
|
// activeBlobs,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// totalAccounts,
|
|
|
|
|
|
|
|
// activeAccounts,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// channelsArchived,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
launchTime: +new Date(),
|
|
|
|
|
|
|
|
// runningTime,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// the administrator should have set an 'inactiveTime' in their config
|
|
|
|
// the administrator should have set an 'inactiveTime' in their config
|
|
|
|
// if they didn't, just exit.
|
|
|
|
// if they didn't, just exit.
|
|
|
@ -81,7 +101,9 @@ module.exports = function (Env, cb) {
|
|
|
|
TODO make this configurable ?
|
|
|
|
TODO make this configurable ?
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
var BLOOM_CAPACITY = (1 << 20) - 1; // over a million items
|
|
|
|
var BLOOM_CAPACITY = (1 << 20) - 1; // over a million items
|
|
|
|
var BLOOM_ERROR = 1 / 1000; // an error rate of one in a thousand
|
|
|
|
var BLOOM_ERROR = 1 / 10000; // an error rate of one in a thousand
|
|
|
|
|
|
|
|
// the number of ms artificially introduced between CPU-intensive operations
|
|
|
|
|
|
|
|
var THROTTLE_FACTOR = 10;
|
|
|
|
|
|
|
|
|
|
|
|
// we'll use one filter for the set of active documents
|
|
|
|
// we'll use one filter for the set of active documents
|
|
|
|
var activeDocs = Bloom.optimalFilter(BLOOM_CAPACITY, BLOOM_ERROR);
|
|
|
|
var activeDocs = Bloom.optimalFilter(BLOOM_CAPACITY, BLOOM_ERROR);
|
|
|
@ -152,6 +174,8 @@ module.exports = function (Env, cb) {
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
return Log.error('EVICT_ARCHIVED_FINAL_ERROR', err);
|
|
|
|
return Log.error('EVICT_ARCHIVED_FINAL_ERROR', err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
report.archivedChannelsRemoved = removed;
|
|
|
|
|
|
|
|
report.archivedAccountsRemoved = accounts;
|
|
|
|
Log.info('EVICT_ARCHIVED_CHANNELS_REMOVED', removed);
|
|
|
|
Log.info('EVICT_ARCHIVED_CHANNELS_REMOVED', removed);
|
|
|
|
Log.info('EVICT_ARCHIVED_ACCOUNTS_REMOVED', accounts);
|
|
|
|
Log.info('EVICT_ARCHIVED_ACCOUNTS_REMOVED', accounts);
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -165,6 +189,7 @@ module.exports = function (Env, cb) {
|
|
|
|
// if they are older than the specified retention time
|
|
|
|
// if they are older than the specified retention time
|
|
|
|
var removed = 0;
|
|
|
|
var removed = 0;
|
|
|
|
blobs.list.archived.proofs(function (err, item, next) {
|
|
|
|
blobs.list.archived.proofs(function (err, item, next) {
|
|
|
|
|
|
|
|
next = Util.mkAsync(next, THROTTLE_FACTOR);
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
Log.error("EVICT_BLOB_LIST_ARCHIVED_PROOF_ERROR", err);
|
|
|
|
Log.error("EVICT_BLOB_LIST_ARCHIVED_PROOF_ERROR", err);
|
|
|
|
return void next();
|
|
|
|
return void next();
|
|
|
@ -180,6 +205,7 @@ module.exports = function (Env, cb) {
|
|
|
|
next();
|
|
|
|
next();
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
}, w(function () {
|
|
|
|
}, w(function () {
|
|
|
|
|
|
|
|
report.archivedBlobProofsRemoved = removed;
|
|
|
|
Log.info('EVICT_ARCHIVED_BLOB_PROOFS_REMOVED', removed);
|
|
|
|
Log.info('EVICT_ARCHIVED_BLOB_PROOFS_REMOVED', removed);
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -190,6 +216,7 @@ module.exports = function (Env, cb) {
|
|
|
|
// if they are older than the specified retention time
|
|
|
|
// if they are older than the specified retention time
|
|
|
|
var removed = 0;
|
|
|
|
var removed = 0;
|
|
|
|
blobs.list.archived.blobs(function (err, item, next) {
|
|
|
|
blobs.list.archived.blobs(function (err, item, next) {
|
|
|
|
|
|
|
|
next = Util.mkAsync(next, THROTTLE_FACTOR);
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
Log.error("EVICT_BLOB_LIST_ARCHIVED_BLOBS_ERROR", err);
|
|
|
|
Log.error("EVICT_BLOB_LIST_ARCHIVED_BLOBS_ERROR", err);
|
|
|
|
return void next();
|
|
|
|
return void next();
|
|
|
@ -205,6 +232,7 @@ module.exports = function (Env, cb) {
|
|
|
|
next();
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}, w(function () {
|
|
|
|
}, w(function () {
|
|
|
|
|
|
|
|
report.archivedBlobsRemoved = removed;
|
|
|
|
Log.info('EVICT_ARCHIVED_BLOBS_REMOVED', removed);
|
|
|
|
Log.info('EVICT_ARCHIVED_BLOBS_REMOVED', removed);
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -232,6 +260,8 @@ module.exports = function (Env, cb) {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var done = function () {
|
|
|
|
var done = function () {
|
|
|
|
|
|
|
|
report.activeChannels = active;
|
|
|
|
|
|
|
|
report.totalChannels = channels;
|
|
|
|
Log.info('EVICT_CHANNELS_CATEGORIZED', {
|
|
|
|
Log.info('EVICT_CHANNELS_CATEGORIZED', {
|
|
|
|
active: active,
|
|
|
|
active: active,
|
|
|
|
channels: channels,
|
|
|
|
channels: channels,
|
|
|
@ -246,6 +276,7 @@ module.exports = function (Env, cb) {
|
|
|
|
var active = 0;
|
|
|
|
var active = 0;
|
|
|
|
|
|
|
|
|
|
|
|
blobs.list.blobs(function (err, item, next) {
|
|
|
|
blobs.list.blobs(function (err, item, next) {
|
|
|
|
|
|
|
|
next = Util.mkAsync(next, THROTTLE_FACTOR);
|
|
|
|
n_blobs++;
|
|
|
|
n_blobs++;
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
Log.error("EVICT_BLOB_CATEGORIZATION", err);
|
|
|
|
Log.error("EVICT_BLOB_CATEGORIZATION", err);
|
|
|
@ -262,6 +293,8 @@ module.exports = function (Env, cb) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
next();
|
|
|
|
next();
|
|
|
|
}, w(function () {
|
|
|
|
}, w(function () {
|
|
|
|
|
|
|
|
report.totalBlobs = n_blobs;
|
|
|
|
|
|
|
|
report.activeBlobs = active;
|
|
|
|
Log.info('EVICT_BLOBS_CATEGORIZED', {
|
|
|
|
Log.info('EVICT_BLOBS_CATEGORIZED', {
|
|
|
|
active: active,
|
|
|
|
active: active,
|
|
|
|
blobs: n_blobs,
|
|
|
|
blobs: n_blobs,
|
|
|
@ -311,6 +344,7 @@ module.exports = function (Env, cb) {
|
|
|
|
// otherwise, we'll only retain data from active accounts
|
|
|
|
// otherwise, we'll only retain data from active accounts
|
|
|
|
// so we need more heuristics
|
|
|
|
// so we need more heuristics
|
|
|
|
var handler = function (content, id, next) {
|
|
|
|
var handler = function (content, id, next) {
|
|
|
|
|
|
|
|
next = Util.mkAsync(next, THROTTLE_FACTOR);
|
|
|
|
accounts++;
|
|
|
|
accounts++;
|
|
|
|
|
|
|
|
|
|
|
|
var mtime = content.latest;
|
|
|
|
var mtime = content.latest;
|
|
|
@ -327,6 +361,10 @@ module.exports = function (Env, cb) {
|
|
|
|
// we plan to delete them, because it may be interesting information
|
|
|
|
// we plan to delete them, because it may be interesting information
|
|
|
|
inactive++;
|
|
|
|
inactive++;
|
|
|
|
if (PRESERVE_INACTIVE_ACCOUNTS) {
|
|
|
|
if (PRESERVE_INACTIVE_ACCOUNTS) {
|
|
|
|
|
|
|
|
Log.info('EVICT_INACTIVE_ACCOUNT_PRESERVED', {
|
|
|
|
|
|
|
|
id: id,
|
|
|
|
|
|
|
|
mtime: mtime,
|
|
|
|
|
|
|
|
});
|
|
|
|
pinAll(pinList);
|
|
|
|
pinAll(pinList);
|
|
|
|
return void next();
|
|
|
|
return void next();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -356,9 +394,8 @@ module.exports = function (Env, cb) {
|
|
|
|
"EVICT_COUNT_ACCOUNTS":
|
|
|
|
"EVICT_COUNT_ACCOUNTS":
|
|
|
|
"EVICT_INACTIVE_ACCOUNTS";
|
|
|
|
"EVICT_INACTIVE_ACCOUNTS";
|
|
|
|
|
|
|
|
|
|
|
|
// update the number of known active accounts in Env for statistics
|
|
|
|
report.totalAccounts = accounts;
|
|
|
|
Env.knownActiveAccounts = accounts - inactive;
|
|
|
|
report.activeAccounts = accounts - inactive;
|
|
|
|
|
|
|
|
|
|
|
|
Log.info(label, {
|
|
|
|
Log.info(label, {
|
|
|
|
accounts: accounts,
|
|
|
|
accounts: accounts,
|
|
|
|
inactive: inactive,
|
|
|
|
inactive: inactive,
|
|
|
@ -375,7 +412,9 @@ module.exports = function (Env, cb) {
|
|
|
|
// iterate over blobs and remove them
|
|
|
|
// iterate over blobs and remove them
|
|
|
|
// if they have not been accessed within the specified retention time
|
|
|
|
// if they have not been accessed within the specified retention time
|
|
|
|
var removed = 0;
|
|
|
|
var removed = 0;
|
|
|
|
|
|
|
|
var total = 0;
|
|
|
|
blobs.list.blobs(function (err, item, next) {
|
|
|
|
blobs.list.blobs(function (err, item, next) {
|
|
|
|
|
|
|
|
next = Util.mkAsync(next, THROTTLE_FACTOR);
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
Log.error("EVICT_BLOB_LIST_BLOBS_ERROR", err);
|
|
|
|
Log.error("EVICT_BLOB_LIST_BLOBS_ERROR", err);
|
|
|
|
return void next();
|
|
|
|
return void next();
|
|
|
@ -384,6 +423,7 @@ module.exports = function (Env, cb) {
|
|
|
|
next();
|
|
|
|
next();
|
|
|
|
return void Log.error('EVICT_BLOB_LIST_BLOBS_NO_ITEM', item);
|
|
|
|
return void Log.error('EVICT_BLOB_LIST_BLOBS_NO_ITEM', item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
total++;
|
|
|
|
if (pinnedDocs.test(item.blobId)) { return void next(); }
|
|
|
|
if (pinnedDocs.test(item.blobId)) { return void next(); }
|
|
|
|
if (activeDocs.test(item.blobId)) { return void next(); }
|
|
|
|
if (activeDocs.test(item.blobId)) { return void next(); }
|
|
|
|
|
|
|
|
|
|
|
@ -392,6 +432,7 @@ module.exports = function (Env, cb) {
|
|
|
|
// unless we address this race condition with this last-minute double-check
|
|
|
|
// unless we address this race condition with this last-minute double-check
|
|
|
|
if (getNewestTime(item) > inactiveTime) { return void next(); }
|
|
|
|
if (getNewestTime(item) > inactiveTime) { return void next(); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
removed++;
|
|
|
|
blobs.archive.blob(item.blobId, function (err) {
|
|
|
|
blobs.archive.blob(item.blobId, function (err) {
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
Log.error("EVICT_ARCHIVE_BLOB_ERROR", {
|
|
|
|
Log.error("EVICT_ARCHIVE_BLOB_ERROR", {
|
|
|
@ -403,10 +444,11 @@ module.exports = function (Env, cb) {
|
|
|
|
Log.info("EVICT_ARCHIVE_BLOB", {
|
|
|
|
Log.info("EVICT_ARCHIVE_BLOB", {
|
|
|
|
item: item,
|
|
|
|
item: item,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
removed++;
|
|
|
|
|
|
|
|
next();
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}, w(function () {
|
|
|
|
}, w(function () {
|
|
|
|
|
|
|
|
report.totalBlobs = total;
|
|
|
|
|
|
|
|
report.activeBlobs = total - removed;
|
|
|
|
Log.info('EVICT_BLOBS_REMOVED', removed);
|
|
|
|
Log.info('EVICT_BLOBS_REMOVED', removed);
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -416,6 +458,7 @@ module.exports = function (Env, cb) {
|
|
|
|
// if they don't correspond to a pinned or active file
|
|
|
|
// if they don't correspond to a pinned or active file
|
|
|
|
var removed = 0;
|
|
|
|
var removed = 0;
|
|
|
|
blobs.list.proofs(function (err, item, next) {
|
|
|
|
blobs.list.proofs(function (err, item, next) {
|
|
|
|
|
|
|
|
next = Util.mkAsync(next, THROTTLE_FACTOR);
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
next();
|
|
|
|
next();
|
|
|
|
return void Log.error("EVICT_BLOB_LIST_PROOFS_ERROR", err);
|
|
|
|
return void Log.error("EVICT_BLOB_LIST_PROOFS_ERROR", err);
|
|
|
@ -458,6 +501,7 @@ module.exports = function (Env, cb) {
|
|
|
|
var archived = 0;
|
|
|
|
var archived = 0;
|
|
|
|
|
|
|
|
|
|
|
|
var handler = function (err, item, cb) {
|
|
|
|
var handler = function (err, item, cb) {
|
|
|
|
|
|
|
|
cb = Util.mkAsync(cb, THROTTLE_FACTOR);
|
|
|
|
channels++;
|
|
|
|
channels++;
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
Log.error('EVICT_CHANNEL_ITERATION', err);
|
|
|
|
Log.error('EVICT_CHANNEL_ITERATION', err);
|
|
|
@ -514,6 +558,7 @@ module.exports = function (Env, cb) {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var done = function () {
|
|
|
|
var done = function () {
|
|
|
|
|
|
|
|
report.channelsArchived = archived;
|
|
|
|
return void Log.info('EVICT_CHANNELS_ARCHIVED', archived);
|
|
|
|
return void Log.info('EVICT_CHANNELS_ARCHIVED', archived);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -539,8 +584,9 @@ module.exports = function (Env, cb) {
|
|
|
|
.nThen(archiveInactiveBlobProofs)
|
|
|
|
.nThen(archiveInactiveBlobProofs)
|
|
|
|
.nThen(archiveInactiveChannels)
|
|
|
|
.nThen(archiveInactiveChannels)
|
|
|
|
.nThen(function () {
|
|
|
|
.nThen(function () {
|
|
|
|
Log.info("EVICT_TIME_TO_RUN_SCRIPT", msSinceStart());
|
|
|
|
var runningTime = report.runningTime = msSinceStart();
|
|
|
|
|
|
|
|
Log.info("EVICT_TIME_TO_RUN_SCRIPT", runningTime);
|
|
|
|
}).nThen(function () {
|
|
|
|
}).nThen(function () {
|
|
|
|
complete();
|
|
|
|
complete(void 0, report);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|