Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 4x 4x 4x 4x 7x 7x 2x 2x 2x 2x 2x 7x 1x 3x 1x 2x | import { EngineStatus } from "../types.js";
/**
* 複数エンジンの同時実行を制御するコントローラー。
* 特にモバイル環境等でメモリを保護するため、アクティブなエンジン数を制限します。
*/
export class EngineConcurrencyController {
private activeEngines = new Set<string>();
private maxActive: number;
constructor(maxActive?: number) {
// デフォルトは 2 (1つがメイン、1つがバックグラウンド解析用など)
// deviceMemory が低い場合は 1 に制限
const g = globalThis as unknown as {
navigator?: { deviceMemory?: number };
};
const ram = g.navigator?.deviceMemory || 4;
this.maxActive = maxActive || (ram < 4 ? 1 : 2);
}
/**
* エンジンがアクティブ(busy)になる許可を求めます。
* 上限に達している場合は、古いエンジンを停止(サスペンド)させるか、待機させます。
*/
public async requestActive(
engineId: string,
onSuspend?: (targetId: string) => Promise<void>,
): Promise<void> {
Iif (this.activeEngines.has(engineId)) return;
if (this.activeEngines.size >= this.maxActive) {
// 最も古いアクティブエンジンを特定(簡易的に最初の要素)
const oldest = this.activeEngines.values().next().value;
Eif (oldest && oldest !== engineId) {
Eif (onSuspend) {
await onSuspend(oldest);
}
this.activeEngines.delete(oldest);
}
}
this.activeEngines.add(engineId);
}
public releaseActive(engineId: string): void {
this.activeEngines.delete(engineId);
}
public updateStatus(engineId: string, status: EngineStatus): void {
if (status === "busy") {
this.activeEngines.add(engineId);
} else if (Estatus === "ready" || status === "error") {
// 停止した場合は管理から外す(サスペンドの余地を作る)
// ただし、即座に消すとリクエスト時の優先順位がわからなくなるため、
// 実際には LRU キュー等で管理するのが望ましい。
}
}
}
|