Skip to content

Commit

Permalink
cleaner: expose cli task to do cleaning + vacuum
Browse files Browse the repository at this point in the history
Make the cleaner available to users by exposing it as a subcommand
to thelounge storage.

This is recommended to be run whenever the storage policy significantly
changes in a way that makes many messages eligible for deletion.
The cleaner would cope, but it'll be inefficient and can take many hours.
Due to how storage works in sqlite, the space would not actually be
given back to the OS, just marked for future writes.
Hence this also runs a vacuum to compact the DB as much as it can.
  • Loading branch information
brunnre8 committed Dec 24, 2023
1 parent 74aff7e commit 21b1152
Showing 1 changed file with 57 additions and 2 deletions.
59 changes: 57 additions & 2 deletions server/command-line/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import {Command} from "commander";
import ClientManager from "../clientManager";
import Utils from "./utils";
import SqliteMessageStorage from "../plugins/messageStorage/sqlite";
import {StorageCleaner} from "../storageCleaner";

const program = new Command("storage").description(
"various utilities related to the message storage"
);

program
.command("migrate")
.argument("[user]", "migrate a specific user only, all if not provided")
.argument("[username]", "migrate a specific user only, all if not provided")
.description("Migrate message storage where needed")
.on("--help", Utils.extraHelp)
.action(function (user) {
Expand All @@ -20,7 +21,19 @@ program
});
});

async function runMigrations(user: string) {
program
.command("clean")
.argument("[user]", "clean messages for a specific user only, all if not provided")
.description("Delete messages from the DB based on the storage policy")
.on("--help", Utils.extraHelp)
.action(function (user) {
runCleaning(user).catch((err) => {
log.error(err.toString());
process.exit(1);
});
});

async function runMigrations(user?: string) {
const manager = new ClientManager();
const users = manager.getUsers();

Expand Down Expand Up @@ -65,4 +78,46 @@ function isUserLogEnabled(manager: ClientManager, user: string): boolean {
return conf.log;
}

async function runCleaning(user: string) {
const manager = new ClientManager();
const users = manager.getUsers();

if (user) {
if (!users.includes(user)) {
throw new Error(`invalid user ${user}`);
}

return cleanUser(manager, user);
}

for (const name of users) {
await cleanUser(manager, name);
// if any migration fails we blow up,
// chances are the rest won't complete either
}
}

async function cleanUser(manager: ClientManager, user: string) {
log.info("handling user", user);

if (!isUserLogEnabled(manager, user)) {
log.info("logging disabled for user", user, ". Skipping");
return;
}

const sqlite = new SqliteMessageStorage(user);
await sqlite.enable();
const cleaner = new StorageCleaner(sqlite);
const num_deleted = await cleaner.runDeletesNoLimit();
log.info(`deleted ${num_deleted} messages`);
log.info("running a vacuum now, this might take a while");

if (num_deleted > 0) {
await sqlite.vacuum();
}

await sqlite.close();
log.info(`cleaning messages for ${user} has been successful`);
}

export default program;

0 comments on commit 21b1152

Please sign in to comment.