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)!;
return await scheduler.schedule(
async () => file.size,
async () => {
return await scheduler.schedule(file.size, async () => {
state.status = "encryption-pending";
try {
@@ -267,6 +265,5 @@ export const uploadFile = async (
state.status = "error";
throw e;
}
},
);
});
};

View File

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