storage: make remove and removeDir async
This commit is contained in:
@@ -39,6 +39,7 @@ const assert = require('assert'),
|
||||
path = require('path'),
|
||||
S3BlockReadStream = require('s3-block-read-stream'),
|
||||
safe = require('safetydance'),
|
||||
util = require('util'),
|
||||
_ = require('underscore');
|
||||
|
||||
let aws = AwsSdk;
|
||||
@@ -385,10 +386,9 @@ function copy(apiConfig, oldFilePath, newFilePath) {
|
||||
return events;
|
||||
}
|
||||
|
||||
function remove(apiConfig, filename, callback) {
|
||||
async function remove(apiConfig, filename) {
|
||||
assert.strictEqual(typeof apiConfig, 'object');
|
||||
assert.strictEqual(typeof filename, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
const credentials = getS3Config(apiConfig);
|
||||
|
||||
@@ -402,57 +402,48 @@ function remove(apiConfig, filename, callback) {
|
||||
};
|
||||
|
||||
// deleteObjects does not return error if key is not found
|
||||
s3.deleteObjects(deleteParams, function (error) {
|
||||
if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Unable to remove ${deleteParams.Key}. error: ${error.message || error.code}`)); // DO sets 'code'
|
||||
|
||||
callback(null);
|
||||
});
|
||||
const [error] = await safe(s3.deleteObjects(deleteParams).promise());
|
||||
if (error) throw new BoxError(BoxError.EXTERNAL_ERROR, `Unable to remove ${deleteParams.Key}. error: ${error.message}`);
|
||||
}
|
||||
|
||||
function removeDir(apiConfig, pathPrefix) {
|
||||
async function removeDir(apiConfig, pathPrefix, progressCallback) {
|
||||
assert.strictEqual(typeof apiConfig, 'object');
|
||||
assert.strictEqual(typeof pathPrefix, 'string');
|
||||
assert.strictEqual(typeof progressCallback, 'function');
|
||||
|
||||
const events = new EventEmitter();
|
||||
let total = 0;
|
||||
|
||||
const credentials = getS3Config(apiConfig);
|
||||
|
||||
const s3 = new aws.S3(credentials);
|
||||
const listDirAsync = util.promisify(listDir);
|
||||
|
||||
listDir(apiConfig, pathPrefix, 1000, function listDirIterator(entries, done) {
|
||||
let total = 0;
|
||||
|
||||
await listDirAsync(apiConfig, pathPrefix, 1000, function listDirIterator(entries, done) {
|
||||
total += entries.length;
|
||||
|
||||
const chunkSize = apiConfig.deleteConcurrency || (apiConfig.provider !== 'digitalocean-spaces' ? 1000 : 100); // throttle objects in each request
|
||||
var chunks = chunk(entries, chunkSize);
|
||||
const chunks = chunk(entries, chunkSize);
|
||||
|
||||
async.eachSeries(chunks, function deleteFiles(objects, iteratorCallback) {
|
||||
var deleteParams = {
|
||||
async.eachSeries(chunks, async function deleteFiles(objects) {
|
||||
const deleteParams = {
|
||||
Bucket: apiConfig.bucket,
|
||||
Delete: {
|
||||
Objects: objects.map(function (o) { return { Key: o.fullPath }; })
|
||||
}
|
||||
};
|
||||
|
||||
events.emit('progress', `Removing ${objects.length} files from ${objects[0].fullPath} to ${objects[objects.length-1].fullPath}`);
|
||||
progressCallback({ message: `Removing ${objects.length} files from ${objects[0].fullPath} to ${objects[objects.length-1].fullPath}` });
|
||||
|
||||
// deleteObjects does not return error if key is not found
|
||||
s3.deleteObjects(deleteParams, function (error /*, deleteData */) {
|
||||
if (error) {
|
||||
events.emit('progress', `Unable to remove ${deleteParams.Key} ${error.message || error.code}`);
|
||||
return iteratorCallback(new BoxError(BoxError.EXTERNAL_ERROR, `Unable to remove ${deleteParams.Key}. error: ${error.message || error.code}`)); // DO sets 'code'
|
||||
}
|
||||
|
||||
iteratorCallback(null);
|
||||
});
|
||||
const [error] = await safe(s3.deleteObjects(deleteParams).promise());
|
||||
if (error) {
|
||||
progressCallback({ message: `Unable to remove ${deleteParams.Key} ${error.message || error.code}` });
|
||||
throw new BoxError(BoxError.EXTERNAL_ERROR, `Unable to remove ${deleteParams.Key}. error: ${error.message}`);
|
||||
}
|
||||
}, done);
|
||||
}, function (error) {
|
||||
events.emit('progress', `Removed ${total} files`);
|
||||
|
||||
process.nextTick(() => events.emit('done', error));
|
||||
});
|
||||
|
||||
return events;
|
||||
progressCallback({ message: `Removed ${total} files` });
|
||||
}
|
||||
|
||||
async function remount(apiConfig) {
|
||||
|
||||
Reference in New Issue
Block a user