mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
42959d66db
* wip * Implementation complete * tidying * test * Address feedback * Remove duplicative retry logic from UpdateDocumentsPopularityScoreTask. Now that we're split across many runs this is not neccessary * Refactor to subclass, config to instance * Refactor BaseTask to named export * fix: Missing partition * tsc * Feedback
74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
import { Sema } from "async-sema";
|
|
import Logger from "@server/logging/Logger";
|
|
import { Attachment } from "@server/models";
|
|
import FileStorage from "@server/storage/files";
|
|
import { BaseTask, TaskPriority } from "./base/BaseTask";
|
|
import env from "@server/env";
|
|
|
|
const ConcurrentUploads = 5;
|
|
|
|
type Item = {
|
|
/** The ID of the attachment */
|
|
attachmentId: string;
|
|
/** The remote URL to upload */
|
|
url: string;
|
|
};
|
|
|
|
/**
|
|
* A task that uploads a list of provided urls to known attachments.
|
|
*/
|
|
export default class UploadAttachmentsForImportTask extends BaseTask<Item[]> {
|
|
public async perform(items: Item[]) {
|
|
const sema = new Sema(ConcurrentUploads, {
|
|
// perf: pre-allocate the queue size
|
|
capacity:
|
|
items.length > ConcurrentUploads ? items.length : ConcurrentUploads,
|
|
});
|
|
|
|
const uploadPromises = items.map(async (item) => {
|
|
try {
|
|
await sema.acquire();
|
|
|
|
const attachment = await Attachment.findByPk(item.attachmentId, {
|
|
rejectOnEmpty: true,
|
|
});
|
|
|
|
// This means the attachment has already been uploaded.
|
|
if (String(attachment.size) !== "0") {
|
|
return;
|
|
}
|
|
|
|
const res = await FileStorage.storeFromUrl(
|
|
item.url,
|
|
attachment.key,
|
|
attachment.acl,
|
|
{
|
|
timeout: env.FILE_STORAGE_IMPORT_TIMEOUT,
|
|
}
|
|
);
|
|
|
|
if (res) {
|
|
await attachment.update({
|
|
size: res.contentLength,
|
|
contentType: res.contentType,
|
|
});
|
|
}
|
|
} catch (err) {
|
|
Logger.error("error uploading attachments for import", err);
|
|
throw err;
|
|
} finally {
|
|
sema.release();
|
|
}
|
|
});
|
|
|
|
return await Promise.all(uploadPromises);
|
|
}
|
|
|
|
public get options() {
|
|
return {
|
|
attempts: 3,
|
|
priority: TaskPriority.Normal,
|
|
};
|
|
}
|
|
}
|