refactor(rclone): cache temizlemeyi RC API üzerinden yap
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.
This commit is contained in:
@@ -7,7 +7,7 @@ import path from "path";
|
|||||||
import mime from "mime-types";
|
import mime from "mime-types";
|
||||||
import { v2 as webdav } from "webdav-server";
|
import { v2 as webdav } from "webdav-server";
|
||||||
import { fileURLToPath } from "url";
|
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 crypto from "crypto"; // 🔒 basit token üretimi için
|
||||||
import { getDiskSpace, getDownloadsSize } from "./utils/diskSpace.js";
|
import { getDiskSpace, getDownloadsSize } from "./utils/diskSpace.js";
|
||||||
import { createAuth } from "./modules/auth.js";
|
import { createAuth } from "./modules/auth.js";
|
||||||
@@ -1004,11 +1004,17 @@ function startRcloneCacheCleanSchedule(minutes) {
|
|||||||
if (!interval || interval <= 0) return;
|
if (!interval || interval <= 0) return;
|
||||||
rcloneCacheCleanTimer = setInterval(() => {
|
rcloneCacheCleanTimer = setInterval(() => {
|
||||||
if (!RCLONE_RC_ENABLED) return;
|
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) => {
|
.then((resp) => {
|
||||||
if (resp.status === 404) {
|
if (resp.status === 404) {
|
||||||
return fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/refresh`, {
|
return fetch(`http://${RCLONE_RC_ADDR}/rc/vfs/forget`, {
|
||||||
method: "POST"
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ path: "", recursive: true })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
@@ -1023,21 +1029,37 @@ function startRcloneCacheCleanSchedule(minutes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function runRcloneCacheClean() {
|
async function runRcloneCacheClean() {
|
||||||
const settings = loadRcloneSettings();
|
|
||||||
const wasRunning = Boolean(rcloneProcess && !rcloneProcess.killed);
|
const wasRunning = Boolean(rcloneProcess && !rcloneProcess.killed);
|
||||||
if (wasRunning) {
|
|
||||||
stopRcloneMount();
|
|
||||||
}
|
|
||||||
try {
|
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.rmSync(RCLONE_VFS_CACHE_DIR, { recursive: true, force: true });
|
||||||
fs.mkdirSync(RCLONE_VFS_CACHE_DIR, { recursive: 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 };
|
return { ok: true, method: "fs", restarted: false };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return { ok: false, error: err?.message || String(err) };
|
return { ok: false, error: err?.message || String(err) };
|
||||||
@@ -1058,8 +1080,23 @@ function isRcloneMounted(mountDir) {
|
|||||||
|
|
||||||
function ensureRcloneDirs(settings) {
|
function ensureRcloneDirs(settings) {
|
||||||
if (!settings?.mountDir) return;
|
if (!settings?.mountDir) return;
|
||||||
if (!fs.existsSync(settings.mountDir)) {
|
const mountDir = settings.mountDir;
|
||||||
fs.mkdirSync(settings.mountDir, { recursive: true });
|
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)) {
|
if (!fs.existsSync(RCLONE_VFS_CACHE_DIR)) {
|
||||||
fs.mkdirSync(RCLONE_VFS_CACHE_DIR, { recursive: true });
|
fs.mkdirSync(RCLONE_VFS_CACHE_DIR, { recursive: true });
|
||||||
|
|||||||
Reference in New Issue
Block a user