Created
June 18, 2024 21:19
-
-
Save panphora/b24d2d0ddc8903c28fd900ba0694d038 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Files in directories in "ephemeral" will be deleted | |
when they're older than the name specified by the directory | |
For example: | |
- Files in directory "min5" won't be older than 5 minutes | |
- Files in directory "min15" won't be older than 15 minutes | |
- Files in directory "day30" won't be older than 30 days | |
Time is fuzzy because the cron runs every 1min, so a file might | |
last 6 minutes in a directory called "min5" | |
No need to worry about the Node app always being on, as soon as | |
it starts back up, it will clear the older files within 1 min | |
*/ | |
import { promises as fs } from "fs"; | |
import path from "upath"; | |
import cron from "node-cron"; | |
import basedir from "#root/server-lib/basedir.js"; | |
const targetDirectory = path.join(basedir, "ephemeral"); | |
/** | |
* Sets up a single cron job that runs every 5 minutes for each sub-directory in the base directory, | |
* deleting files older than the age limit implied by the sub-directory name. | |
*/ | |
async function setupCronJobForSubDirs(baseDir) { | |
cron.schedule('* * * * *', async () => { | |
try { | |
const dirs = await fs.readdir(baseDir); | |
for (const dir of dirs) { | |
const dirPath = path.join(baseDir, dir); | |
const ageLimit = parseDirNameToAgeLimit(dir); | |
if (dirPath.includes("/ephemeral/") && ageLimit !== null) { | |
await deleteOldFilesInDir(dirPath, ageLimit); | |
} | |
} | |
} catch (error) { | |
console.error(`Error in cron job: ${error}`); | |
} | |
}); | |
console.log(`Cron job scheduled to run every 1 minute for directories in ${baseDir}`); | |
} | |
/** | |
* Converts a directory name to an age limit in milliseconds. | |
*/ | |
function parseDirNameToAgeLimit(dirName) { | |
const match = dirName.match(/(min|hour|day)s?(\d+)/); | |
if (!match) return null; | |
const [, unit, value] = match; | |
let ageLimit; | |
switch (unit) { | |
case 'min': | |
ageLimit = parseInt(value, 10) * 60 * 1000; // milliseconds | |
break; | |
case 'hour': | |
ageLimit = parseInt(value, 10) * 60 * 60 * 1000; // milliseconds | |
break; | |
case 'day': | |
ageLimit = parseInt(value, 10) * 24 * 60 * 60 * 1000; // milliseconds | |
break; | |
default: | |
return null; | |
} | |
return ageLimit; | |
} | |
/** | |
* Deletes files older than a specified age limit within a directory. | |
*/ | |
async function deleteOldFilesInDir(dirPath, ageLimit) { | |
try { | |
const files = await fs.readdir(dirPath); | |
const now = new Date(); | |
for (const file of files) { | |
if (file.includes(".gitkeep")) { | |
return; | |
} | |
const filePath = path.join(dirPath, file); | |
const fileStats = await fs.stat(filePath); | |
const fileAge = now - new Date(fileStats.mtime); | |
if (fileAge > ageLimit) { | |
await fs.unlink(filePath); | |
console.log(`Deleted: ${filePath}`); | |
} | |
} | |
} catch (error) { | |
console.error(`Error in deleteOldFilesInDir: ${error}`); | |
} | |
} | |
// Initialize the cron job setup | |
setupCronJobForSubDirs(targetDirectory); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment