Scheduler 클래스의 스케쥴링 로직 개선

This commit is contained in:
static
2026-01-04 17:54:42 +09:00
parent cf0f8fe0b9
commit 0eb1d29259
2 changed files with 83 additions and 79 deletions

View File

@@ -196,9 +196,7 @@ export const uploadFile = async (
}); });
const state = uploadingFiles.at(-1)!; const state = uploadingFiles.at(-1)!;
return await scheduler.schedule( return await scheduler.schedule(file.size, async () => {
async () => file.size,
async () => {
state.status = "encryption-pending"; state.status = "encryption-pending";
try { try {
@@ -267,6 +265,5 @@ export const uploadFile = async (
state.status = "error"; state.status = "error";
throw e; throw e;
} }
}, });
);
}; };

View File

@@ -1,39 +1,46 @@
export class Scheduler<T = void> { export class Scheduler<T = void> {
private tasks = 0; private isEstimating = false;
private memoryUsage = 0; private memoryUsage = 0;
private queue: (() => void)[] = []; private queue: (() => void)[] = [];
constructor(public memoryLimit = 100 * 1024 * 1024 /* 100 MiB */) {} constructor(public readonly memoryLimit = 100 * 1024 * 1024 /* 100 MiB */) {}
private next() { private next() {
if (this.memoryUsage < this.memoryLimit) { if (!this.isEstimating && this.memoryUsage < this.memoryLimit) {
this.queue.shift()?.(); const resolve = this.queue.shift();
if (resolve) {
this.isEstimating = true;
resolve();
}
} }
} }
async schedule(estimateMemoryUsage: () => Promise<number>, task: () => Promise<T>) { async schedule(
if (this.tasks++ > 0) { estimateMemoryUsage: number | (() => number | Promise<number>),
task: () => Promise<T>,
) {
if (this.isEstimating || this.memoryUsage >= this.memoryLimit) {
await new Promise<void>((resolve) => { await new Promise<void>((resolve) => {
this.queue.push(resolve); this.queue.push(resolve);
}); });
} } else {
this.isEstimating = true;
while (this.memoryUsage >= this.memoryLimit) {
await new Promise<void>((resolve) => {
this.queue.unshift(resolve);
});
} }
let taskMemoryUsage = 0; let taskMemoryUsage = 0;
try { try {
taskMemoryUsage = await estimateMemoryUsage(); taskMemoryUsage =
typeof estimateMemoryUsage === "number" ? estimateMemoryUsage : await estimateMemoryUsage();
this.memoryUsage += taskMemoryUsage; this.memoryUsage += taskMemoryUsage;
} finally {
this.isEstimating = false;
this.next(); this.next();
}
try {
return await task(); return await task();
} finally { } finally {
this.tasks--;
this.memoryUsage -= taskMemoryUsage; this.memoryUsage -= taskMemoryUsage;
this.next(); this.next();
} }