mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
refactor: make healthchecks less expensive
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import * as fs from "node:fs/promises";
|
import * as fs from "node:fs/promises";
|
||||||
import * as npath from "node:path";
|
|
||||||
import { toMessage } from "../../../utils/errors";
|
import { toMessage } from "../../../utils/errors";
|
||||||
import { logger } from "../../../utils/logger";
|
import { logger } from "../../../utils/logger";
|
||||||
import type { VolumeBackend } from "../backend";
|
import type { VolumeBackend } from "../backend";
|
||||||
@@ -40,11 +39,6 @@ const checkHealth = async (config: BackendConfig) => {
|
|||||||
try {
|
try {
|
||||||
await fs.access(config.path);
|
await fs.access(config.path);
|
||||||
|
|
||||||
// Try to create a temporary file to ensure write access
|
|
||||||
const tempFilePath = npath.join(config.path, `.healthcheck-${Date.now()}`);
|
|
||||||
await fs.writeFile(tempFilePath, "healthcheck");
|
|
||||||
await fs.unlink(tempFilePath);
|
|
||||||
|
|
||||||
return { status: BACKEND_STATUS.mounted };
|
return { status: BACKEND_STATUS.mounted };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("Directory health check failed:", error);
|
logger.error("Directory health check failed:", error);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { logger } from "../../../utils/logger";
|
|||||||
import { getMountForPath } from "../../../utils/mountinfo";
|
import { getMountForPath } from "../../../utils/mountinfo";
|
||||||
import { withTimeout } from "../../../utils/timeout";
|
import { withTimeout } from "../../../utils/timeout";
|
||||||
import type { VolumeBackend } from "../backend";
|
import type { VolumeBackend } from "../backend";
|
||||||
import { createTestFile, executeMount, executeUnmount } from "../utils/backend-utils";
|
import { executeMount, executeUnmount } from "../utils/backend-utils";
|
||||||
import { BACKEND_STATUS, type BackendConfig } from "~/schemas/volumes";
|
import { BACKEND_STATUS, type BackendConfig } from "~/schemas/volumes";
|
||||||
|
|
||||||
const mount = async (config: BackendConfig, path: string) => {
|
const mount = async (config: BackendConfig, path: string) => {
|
||||||
@@ -22,7 +22,7 @@ const mount = async (config: BackendConfig, path: string) => {
|
|||||||
return { status: BACKEND_STATUS.error, error: "NFS mounting is only supported on Linux hosts." };
|
return { status: BACKEND_STATUS.error, error: "NFS mounting is only supported on Linux hosts." };
|
||||||
}
|
}
|
||||||
|
|
||||||
const { status } = await checkHealth(path, config.readOnly ?? false);
|
const { status } = await checkHealth(path);
|
||||||
if (status === "mounted") {
|
if (status === "mounted") {
|
||||||
return { status: BACKEND_STATUS.mounted };
|
return { status: BACKEND_STATUS.mounted };
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ const unmount = async (path: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkHealth = async (path: string, readOnly: boolean) => {
|
const checkHealth = async (path: string) => {
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
logger.debug(`Checking health of NFS volume at ${path}...`);
|
logger.debug(`Checking health of NFS volume at ${path}...`);
|
||||||
await fs.access(path);
|
await fs.access(path);
|
||||||
@@ -98,10 +98,6 @@ const checkHealth = async (path: string, readOnly: boolean) => {
|
|||||||
throw new Error(`Path ${path} is not mounted as NFS.`);
|
throw new Error(`Path ${path} is not mounted as NFS.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!readOnly) {
|
|
||||||
await createTestFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug(`NFS volume at ${path} is healthy and mounted.`);
|
logger.debug(`NFS volume at ${path} is healthy and mounted.`);
|
||||||
return { status: BACKEND_STATUS.mounted };
|
return { status: BACKEND_STATUS.mounted };
|
||||||
};
|
};
|
||||||
@@ -117,5 +113,5 @@ const checkHealth = async (path: string, readOnly: boolean) => {
|
|||||||
export const makeNfsBackend = (config: BackendConfig, path: string): VolumeBackend => ({
|
export const makeNfsBackend = (config: BackendConfig, path: string): VolumeBackend => ({
|
||||||
mount: () => mount(config, path),
|
mount: () => mount(config, path),
|
||||||
unmount: () => unmount(path),
|
unmount: () => unmount(path),
|
||||||
checkHealth: () => checkHealth(path, config.readOnly ?? false),
|
checkHealth: () => checkHealth(path),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { logger } from "../../../utils/logger";
|
|||||||
import { getMountForPath } from "../../../utils/mountinfo";
|
import { getMountForPath } from "../../../utils/mountinfo";
|
||||||
import { withTimeout } from "../../../utils/timeout";
|
import { withTimeout } from "../../../utils/timeout";
|
||||||
import type { VolumeBackend } from "../backend";
|
import type { VolumeBackend } from "../backend";
|
||||||
import { createTestFile, executeMount, executeUnmount } from "../utils/backend-utils";
|
import { executeMount, executeUnmount } from "../utils/backend-utils";
|
||||||
import { BACKEND_STATUS, type BackendConfig } from "~/schemas/volumes";
|
import { BACKEND_STATUS, type BackendConfig } from "~/schemas/volumes";
|
||||||
|
|
||||||
const mount = async (config: BackendConfig, path: string) => {
|
const mount = async (config: BackendConfig, path: string) => {
|
||||||
@@ -22,7 +22,7 @@ const mount = async (config: BackendConfig, path: string) => {
|
|||||||
return { status: BACKEND_STATUS.error, error: "SMB mounting is only supported on Linux hosts." };
|
return { status: BACKEND_STATUS.error, error: "SMB mounting is only supported on Linux hosts." };
|
||||||
}
|
}
|
||||||
|
|
||||||
const { status } = await checkHealth(path, config.readOnly ?? false);
|
const { status } = await checkHealth(path);
|
||||||
if (status === "mounted") {
|
if (status === "mounted") {
|
||||||
return { status: BACKEND_STATUS.mounted };
|
return { status: BACKEND_STATUS.mounted };
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ const unmount = async (path: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkHealth = async (path: string, readOnly: boolean) => {
|
const checkHealth = async (path: string) => {
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
logger.debug(`Checking health of SMB volume at ${path}...`);
|
logger.debug(`Checking health of SMB volume at ${path}...`);
|
||||||
await fs.access(path);
|
await fs.access(path);
|
||||||
@@ -111,10 +111,6 @@ const checkHealth = async (path: string, readOnly: boolean) => {
|
|||||||
throw new Error(`Path ${path} is not mounted as CIFS/SMB.`);
|
throw new Error(`Path ${path} is not mounted as CIFS/SMB.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!readOnly) {
|
|
||||||
await createTestFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug(`SMB volume at ${path} is healthy and mounted.`);
|
logger.debug(`SMB volume at ${path} is healthy and mounted.`);
|
||||||
return { status: BACKEND_STATUS.mounted };
|
return { status: BACKEND_STATUS.mounted };
|
||||||
};
|
};
|
||||||
@@ -130,5 +126,5 @@ const checkHealth = async (path: string, readOnly: boolean) => {
|
|||||||
export const makeSmbBackend = (config: BackendConfig, path: string): VolumeBackend => ({
|
export const makeSmbBackend = (config: BackendConfig, path: string): VolumeBackend => ({
|
||||||
mount: () => mount(config, path),
|
mount: () => mount(config, path),
|
||||||
unmount: () => unmount(path),
|
unmount: () => unmount(path),
|
||||||
checkHealth: () => checkHealth(path, config.readOnly ?? false),
|
checkHealth: () => checkHealth(path),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { logger } from "../../../utils/logger";
|
|||||||
import { getMountForPath } from "../../../utils/mountinfo";
|
import { getMountForPath } from "../../../utils/mountinfo";
|
||||||
import { withTimeout } from "../../../utils/timeout";
|
import { withTimeout } from "../../../utils/timeout";
|
||||||
import type { VolumeBackend } from "../backend";
|
import type { VolumeBackend } from "../backend";
|
||||||
import { createTestFile, executeMount, executeUnmount } from "../utils/backend-utils";
|
import { executeMount, executeUnmount } from "../utils/backend-utils";
|
||||||
import { BACKEND_STATUS, type BackendConfig } from "~/schemas/volumes";
|
import { BACKEND_STATUS, type BackendConfig } from "~/schemas/volumes";
|
||||||
|
|
||||||
const execFile = promisify(execFileCb);
|
const execFile = promisify(execFileCb);
|
||||||
@@ -26,7 +26,7 @@ const mount = async (config: BackendConfig, path: string) => {
|
|||||||
return { status: BACKEND_STATUS.error, error: "WebDAV mounting is only supported on Linux hosts." };
|
return { status: BACKEND_STATUS.error, error: "WebDAV mounting is only supported on Linux hosts." };
|
||||||
}
|
}
|
||||||
|
|
||||||
const { status } = await checkHealth(path, config.readOnly ?? false);
|
const { status } = await checkHealth(path);
|
||||||
if (status === "mounted") {
|
if (status === "mounted") {
|
||||||
return { status: BACKEND_STATUS.mounted };
|
return { status: BACKEND_STATUS.mounted };
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ const unmount = async (path: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkHealth = async (path: string, readOnly: boolean) => {
|
const checkHealth = async (path: string) => {
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
logger.debug(`Checking health of WebDAV volume at ${path}...`);
|
logger.debug(`Checking health of WebDAV volume at ${path}...`);
|
||||||
await fs.access(path);
|
await fs.access(path);
|
||||||
@@ -145,10 +145,6 @@ const checkHealth = async (path: string, readOnly: boolean) => {
|
|||||||
throw new Error(`Path ${path} is not mounted as WebDAV.`);
|
throw new Error(`Path ${path} is not mounted as WebDAV.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!readOnly) {
|
|
||||||
await createTestFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug(`WebDAV volume at ${path} is healthy and mounted.`);
|
logger.debug(`WebDAV volume at ${path} is healthy and mounted.`);
|
||||||
return { status: BACKEND_STATUS.mounted };
|
return { status: BACKEND_STATUS.mounted };
|
||||||
};
|
};
|
||||||
@@ -164,5 +160,5 @@ const checkHealth = async (path: string, readOnly: boolean) => {
|
|||||||
export const makeWebdavBackend = (config: BackendConfig, path: string): VolumeBackend => ({
|
export const makeWebdavBackend = (config: BackendConfig, path: string): VolumeBackend => ({
|
||||||
mount: () => mount(config, path),
|
mount: () => mount(config, path),
|
||||||
unmount: () => unmount(path),
|
unmount: () => unmount(path),
|
||||||
checkHealth: () => checkHealth(path, config.readOnly ?? false),
|
checkHealth: () => checkHealth(path),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ export const startup = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scheduler.build(CleanupDanglingMountsJob).schedule("0 * * * *");
|
Scheduler.build(CleanupDanglingMountsJob).schedule("0 * * * *");
|
||||||
Scheduler.build(VolumeHealthCheckJob).schedule("*/5 * * * *");
|
Scheduler.build(VolumeHealthCheckJob).schedule("*/30 * * * *");
|
||||||
Scheduler.build(RepositoryHealthCheckJob).schedule("*/10 * * * *");
|
Scheduler.build(RepositoryHealthCheckJob).schedule("0 * * * *");
|
||||||
Scheduler.build(BackupExecutionJob).schedule("* * * * *");
|
Scheduler.build(BackupExecutionJob).schedule("* * * * *");
|
||||||
Scheduler.build(CleanupSessionsJob).schedule("0 0 * * *");
|
Scheduler.build(CleanupSessionsJob).schedule("0 0 * * *");
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user