fix(plugin-manager): xoa/add dir luu dung dir moi (stale closure); loc plugin file da mat khoi disk; scan VST3 giam timeout module con lai 4s va subprocess 300s

This commit is contained in:
2026-08-22 15:10:35 +07:00
parent c07b792bd4
commit 681cab4f25
4 changed files with 39 additions and 24 deletions
+6 -1
View File
@@ -550,7 +550,7 @@ class PluginManager:
for d in dirs:
try:
r = subprocess.run([exe, "--scan", d], capture_output=True,
text=True, timeout=180)
text=True, timeout=300)
except Exception:
continue
if r.returncode != 0:
@@ -578,6 +578,11 @@ class PluginManager:
for e in entries:
if e["path"] in seen:
continue
# Plugin file đã bị xóa khỏi đĩa (dll/vst3 không còn) → loại khỏi
# danh sách ngay (không cache entry chết → MASTERING PANEL / nút
# Synth không còn hiện plugin không dùng được).
if not os.path.exists(e["path"]):
continue
seen.add(e["path"])
uniq.append(e)
# Chỉ cache khi bridge tồn tại: kết quả (kể cả rỗng — dir không có
+12 -7
View File
@@ -6212,15 +6212,16 @@ const PluginManagerModal = ({ isOpen, onClose, pluginsData, onInsertInstrument }
const confirmPluginDir = () => {
const p = pmPicker && pmPicker.path;
if (p && !pmDirs.includes(p)) {
setPmDirs(prev => [...prev, p]);
const next = [...pmDirs, p];
setPmDirs(next);
// TỰ ĐỘNG lưu + scan → nút Synth có ngay danh sách instrument
clearTimeout(window.__pmAutoScanTimer);
window.__pmAutoScanTimer = setTimeout(() => { saveAndScanDirs(); }, 600);
window.__pmAutoScanTimer = setTimeout(() => { saveAndScanDirs(next); }, 600);
}
setPmPicker(null);
};
const pickPluginFolder = async () => {
const addDir = (p) => { if (p && !pmDirs.includes(p)) { setPmDirs(prev => [...prev, p]); clearTimeout(window.__pmAutoScanTimer); window.__pmAutoScanTimer = setTimeout(() => { saveAndScanDirs(); }, 600); } };
const addDir = (p) => { if (p && !pmDirs.includes(p)) { const next = [...pmDirs, p]; setPmDirs(next); clearTimeout(window.__pmAutoScanTimer); window.__pmAutoScanTimer = setTimeout(() => { saveAndScanDirs(next); }, 600); } };
try {
// 1) NATIVE dialog qua engine (Tauri bridge → IFileDialog/Explorer;
// fallback PowerShell/zenity/osascript) — UI chạy localhost:8000 nên
@@ -6250,10 +6251,11 @@ const PluginManagerModal = ({ isOpen, onClose, pluginsData, onInsertInstrument }
}
};
const removePluginDir = (dir) => {
setPmDirs(prev => prev.filter(d => d !== dir));
const next = pmDirs.filter(d => d !== dir);
setPmDirs(next);
// Tự động lưu + scan lại sau khi xóa thư mục
clearTimeout(window.__pmAutoScanTimer);
window.__pmAutoScanTimer = setTimeout(() => { saveAndScanDirs(); }, 600);
window.__pmAutoScanTimer = setTimeout(() => { saveAndScanDirs(next); }, 600);
};
// Expand 1 soundfont → đọc danh sách instrument (bank/program/name) bên trong
// qua API soundfont-instruments/{id} → hiển thị nút "Chèn vào Synth".
@@ -6319,12 +6321,15 @@ const PluginManagerModal = ({ isOpen, onClose, pluginsData, onInsertInstrument }
} catch (err) { showToast('Lỗi: ' + (err.message || err), 'error'); }
};
// Lưu dirs (user override) + scan cả 2 thư mục → refresh list + catalog.
const saveAndScanDirs = async () => {
// dirsOverride: mảng dirs mới nhất (fix stale-closure: setTimeout giữ
// pmDirs cũ nên add/remove xong tự scan lại vẫn lưu dir cũ).
const saveAndScanDirs = async (dirsOverride) => {
const dirs = dirsOverride || pmDirs;
setPmScanning(true);
setPmScanResult('');
setPmScanData(null);
try {
await window.SonicAPI.savePluginDirs({ plugin_dirs: pmDirs });
await window.SonicAPI.savePluginDirs({ plugin_dirs: dirs });
const scan = await window.SonicAPI.scanPluginDirs();
setPmScanData({ vst_found: scan.vst_found || [], soundfonts: scan.soundfonts || [] });
const data = await window.SonicAPI.listPlugins();
File diff suppressed because one or more lines are too long
+4 -1
View File
@@ -1565,7 +1565,10 @@ bool safeScanModule(const std::string& path, std::vector<ScanEntry>& out) {
ScanCtx ctx{&path, &out};
HANDLE hThread = CreateThread(nullptr, 0, scanWorker, &ctx, 0, nullptr);
if (!hThread) { std::cerr << "[Scan] skip (thread fail): " << path << std::endl; return false; }
const DWORD timeoutMs = 12000; // 12s/module — Ozone treo vĩnh viễn, đủ phân biệt
const DWORD timeoutMs = 4000; // 4s/module — module hợp lệ load 1-3s (đo
// thực tế); module treo thì treo vĩnh viễn nên 4s đủ phân biệt. Trước đây
// 12s × ~15 module Ozone 11 treo = 180s+ vượt timeout Python → mất CẢ dir
// → MASTERING PANEL rỗng.
DWORD wait = WaitForSingleObject(hThread, timeoutMs);
if (wait == WAIT_TIMEOUT) {
TerminateThread(hThread, 0);