feat(installer-rp): auto-tune music concurrency to CPU core count
os.cpus().length 기준 동시 다운로드 수를 자동 결정: - 2 코어 이하 → 2 동시 - 3~4 코어 → 3 동시 - 5~8 코어 → 4 동시 - 9 코어 이상 → 5 동시 (YouTube throttle 때문에 상한) 환경변수 MUSIC_CONCURRENCY 로 강제 오버라이드 가능(상한 8). 설치 로그에 감지된 코어 수와 선택된 동시성 노출. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import https from 'node:https'
|
||||
import path from 'node:path'
|
||||
import fs from 'node:fs'
|
||||
import fsp from 'node:fs/promises'
|
||||
import os from 'node:os'
|
||||
import { URL } from 'node:url'
|
||||
import type { ChildProcess } from 'node:child_process'
|
||||
import type { Manifest, PackDefinition, PackList } from '../shared/types.js'
|
||||
@@ -27,8 +28,23 @@ interface RpInstallerState {
|
||||
activeChildren: Set<ChildProcess>
|
||||
}
|
||||
|
||||
/** 동시 yt-dlp 프로세스 수. 너무 높이면 유튜브가 throttle. */
|
||||
const MUSIC_CONCURRENCY = 3
|
||||
/**
|
||||
* 동시 yt-dlp 프로세스 수를 CPU 코어 수로 자동 결정.
|
||||
* - yt-dlp + ffmpeg 변환이 CPU 바운드라 코어 수가 가장 좋은 프록시.
|
||||
* - 유튜브가 IP 단위로 throttle 걸기 때문에 5 이상은 효과 없음 → 상한 5.
|
||||
* - 환경변수 MUSIC_CONCURRENCY 로 강제 오버라이드 가능.
|
||||
*/
|
||||
function pickMusicConcurrency(): number {
|
||||
const override = Number(process.env.MUSIC_CONCURRENCY)
|
||||
if (Number.isFinite(override) && override >= 1) {
|
||||
return Math.min(8, Math.floor(override))
|
||||
}
|
||||
const cores = os.cpus()?.length ?? 4
|
||||
if (cores <= 2) return 2
|
||||
if (cores <= 4) return 3
|
||||
if (cores <= 8) return 4
|
||||
return 5
|
||||
}
|
||||
|
||||
const DEFAULT_MANIFEST_URL = process.env.MANIFEST_URL ?? 'http://127.0.0.1:3000/manifest.json'
|
||||
|
||||
@@ -199,10 +215,13 @@ ipcMain.handle('rp:install:start', async (): Promise<{ resourcepackPath: string
|
||||
sendProgress({ phase: 'prep', message: '준비 완료', done: true })
|
||||
throwIfCancelled()
|
||||
|
||||
// 2-2. 음악 다운로드 (MUSIC_CONCURRENCY 개씩 병렬, ogg 변환)
|
||||
// 2-2. 음악 다운로드 (CPU 코어 수 기반 자동 동시 다운로드, ogg 변환)
|
||||
const musicDir = path.join(tempRoot, 'music')
|
||||
await fsp.mkdir(musicDir, { recursive: true })
|
||||
sendLog(`음악 다운로드 시작 (${musicTotal}곡, 동시 ${MUSIC_CONCURRENCY}개)`)
|
||||
const concurrency = pickMusicConcurrency()
|
||||
const cpuCount = os.cpus()?.length ?? 0
|
||||
sendLog(`CPU 코어 ${cpuCount}개 감지 → 동시 다운로드 ${concurrency}개`)
|
||||
sendLog(`음악 다운로드 시작 (${musicTotal}곡, 동시 ${concurrency}개)`)
|
||||
|
||||
// 클로저 안에서 narrowing 이 풀리지 않도록 로컬 alias.
|
||||
const musicList = pack.list.music
|
||||
@@ -252,7 +271,7 @@ ipcMain.handle('rp:install:start', async (): Promise<{ resourcepackPath: string
|
||||
}
|
||||
}
|
||||
|
||||
const workerCount = Math.min(MUSIC_CONCURRENCY, musicTotal)
|
||||
const workerCount = Math.min(concurrency, musicTotal)
|
||||
const workers: Promise<void>[] = []
|
||||
for (let w = 0; w < workerCount; w++) workers.push(musicWorker())
|
||||
await Promise.all(workers)
|
||||
|
||||
Reference in New Issue
Block a user