From e44c21b36a3505266ccc801950e833a543fa2c98 Mon Sep 17 00:00:00 2001 From: wisecolt Date: Mon, 2 Feb 2026 15:51:18 +0300 Subject: [PATCH] =?UTF-8?q?refactor(rclone):=20cache=20temizlemeyi=20RC=20?= =?UTF-8?q?API=20=C3=BCzerinden=20yap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rclone cache temizleme işlemini artık mount durdurup başlatmak yerine RC API'nin vfs/forget komutunu kullanarak yapar. Bu yöntem daha hızlı ve daha güvenli bir temizleme sağlar. RC API devre dışıyken cache temizleme işlemi yapılmaz ve uyarı döner. Ayrıca mount dizinindeki bağlantı sorunları (ENOTCONN) için otomatik unmount mekanizması eklendi. --- server/server.js | 71 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/server/server.js b/server/server.js index 00ee887..f261187 100644 --- a/server/server.js +++ b/server/server.js @@ -7,7 +7,7 @@ import path from "path"; import mime from "mime-types"; import { v2 as webdav } from "webdav-server"; import { fileURLToPath } from "url"; -import { exec, spawn } from "child_process"; +import { exec, execSync, spawn } from "child_process"; import crypto from "crypto"; // 🔒 basit token üretimi için import { getDiskSpace, getDownloadsSize } from "./utils/diskSpace.js"; import { createAuth } from "./modules/auth.js"; @@ -1004,11 +1004,17 @@ function startRcloneCacheCleanSchedule(minutes) { if (!interval || interval <= 0) return; rcloneCacheCleanTimer = setInterval(() => { if (!RCLONE_RC_ENABLED) return; - fetch(`http://${RCLONE_RC_ADDR}/vfs/refresh`, { method: "POST" }) + fetch(`http://${RCLONE_RC_ADDR}/vfs/forget`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ path: "", recursive: true }) + }) .then((resp) => { if (resp.status === 404) { - return fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/refresh`, { - method: "POST" + return fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/forget`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ path: "", recursive: true }) }); } return resp; @@ -1023,21 +1029,37 @@ function startRcloneCacheCleanSchedule(minutes) { } async function runRcloneCacheClean() { - const settings = loadRcloneSettings(); const wasRunning = Boolean(rcloneProcess && !rcloneProcess.killed); - if (wasRunning) { - stopRcloneMount(); - } try { + if (wasRunning && RCLONE_RC_ENABLED) { + const resp = await fetch(`http://${RCLONE_RC_ADDR}/vfs/forget`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ path: "", recursive: true }) + }); + if (resp.status === 404) { + const fallback = await fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/forget`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ path: "", recursive: true }) + }); + if (!fallback.ok) { + const body = await fallback.text(); + return { ok: false, error: `Rclone RC hata: ${body || fallback.status}` }; + } + } else if (!resp.ok) { + const body = await resp.text(); + return { ok: false, error: `Rclone RC hata: ${body || resp.status}` }; + } + return { ok: true, method: "rc", restarted: false }; + } + + if (wasRunning && !RCLONE_RC_ENABLED) { + return { ok: false, error: "Rclone RC kapalıyken mount durdurulmadan cache temizlenemez." }; + } + fs.rmSync(RCLONE_VFS_CACHE_DIR, { recursive: true, force: true }); fs.mkdirSync(RCLONE_VFS_CACHE_DIR, { recursive: true }); - if (wasRunning) { - const result = startRcloneMount(settings); - if (!result.ok) { - return { ok: false, error: result.error || "Rclone yeniden başlatılamadı" }; - } - return { ok: true, method: "fs", restarted: true }; - } return { ok: true, method: "fs", restarted: false }; } catch (err) { return { ok: false, error: err?.message || String(err) }; @@ -1058,8 +1080,23 @@ function isRcloneMounted(mountDir) { function ensureRcloneDirs(settings) { if (!settings?.mountDir) return; - if (!fs.existsSync(settings.mountDir)) { - fs.mkdirSync(settings.mountDir, { recursive: true }); + const mountDir = settings.mountDir; + try { + if (!fs.existsSync(mountDir)) { + fs.mkdirSync(mountDir, { recursive: true }); + } + } catch (err) { + if (err?.code === "ENOTCONN") { + try { + execSync(`fusermount -u ${JSON.stringify(mountDir)}`, { stdio: "ignore" }); + } catch {} + try { + execSync(`umount -l ${JSON.stringify(mountDir)}`, { stdio: "ignore" }); + } catch {} + fs.mkdirSync(mountDir, { recursive: true }); + } else { + throw err; + } } if (!fs.existsSync(RCLONE_VFS_CACHE_DIR)) { fs.mkdirSync(RCLONE_VFS_CACHE_DIR, { recursive: true });