@mieweb/wikigdrive
Version:
Google Drive to MarkDown synchronization
84 lines (83 loc) • 2.71 kB
JavaScript
import { queue } from 'async';
const __filename = globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).filename;
const CONCURRENCY = 4;
export class QueueDownloader {
constructor(logger) {
Object.defineProperty(this, "q", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "logger", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "progressCallback", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "progress", {
enumerable: true,
configurable: true,
writable: true,
value: {
completed: 0,
total: 0,
warnings: 0,
failed: 0
}
});
this.logger = logger.child({ filename: __filename });
this.q = queue(async (queueTask) => this.processQueueTask(queueTask), CONCURRENCY);
this.q.error((err, queueTask) => {
this.logger.error(err.stack ? err.stack : err.message);
if (403 === err.code) {
this.progress.failed++;
this.logger.error(err.stack ? err.stack : err.message);
this.notify();
return;
}
if (queueTask.retries > 0) {
queueTask.retries--;
this.q.push(queueTask);
}
else {
this.logger.error(err.stack ? err.stack : err.message);
this.progress.failed++;
this.notify();
}
});
}
async processQueueTask(task) {
const subTasks = await task.run();
this.progress.completed++;
this.notify();
for (const subTask of subTasks) {
this.q.push(subTask);
this.progress.total++;
}
this.notify();
await new Promise(resolve => setTimeout(resolve, 100));
}
async finished() {
return this.q.drain();
}
addTask(taskFetchDir) {
this.q.push(taskFetchDir);
this.progress.total++;
this.notify();
}
onProgressNotify(progressCallback) {
this.progressCallback = progressCallback;
}
notify() {
if (this.progressCallback) {
this.progressCallback({ completed: this.progress.completed, total: this.progress.total, warnings: this.progress.warnings, failed: this.progress.failed });
}
}
}