feat(cleanup): implement background cleanup functionality

- Added a new `cleanupAllBackground` function to execute Docker cleanup commands in the background, allowing for immediate return and avoiding gateway timeouts.
- Refactored existing cleanup functions to utilize a centralized `cleanupCommands` object for better maintainability and readability.
This commit is contained in:
Mauricio Siu
2025-12-13 00:57:41 -06:00
parent ee9edd7ff4
commit fea3ec9a6f
2 changed files with 45 additions and 7 deletions

View File

@@ -3,6 +3,7 @@ import {
checkGPUStatus,
checkPortInUse,
cleanupAll,
cleanupAllBackground,
cleanupBuilders,
cleanupContainers,
cleanupImages,
@@ -193,9 +194,10 @@ export const settingsRouter = createTRPCRouter({
cleanAll: adminProcedure
.input(apiServerSchema)
.mutation(async ({ input }) => {
await cleanupAll(input?.serverId);
// Execute cleanup in background and return immediately to avoid gateway timeouts
const result = await cleanupAllBackground(input?.serverId);
return true;
return result;
}),
cleanMonitoring: adminProcedure.mutation(async () => {
if (IS_CLOUD) {

View File

@@ -171,9 +171,17 @@ ${exec}
echo "Execution completed."`;
const cleanupCommands = {
containers: "docker container prune --force",
images: "docker image prune --all --force",
builders: "docker builder prune --all --force",
system: "docker system prune --all --force",
volumes: "docker volume prune --all --force",
};
export const cleanupContainers = async (serverId?: string) => {
try {
const command = "docker container prune --force";
const command = cleanupCommands.containers;
if (serverId) {
await execAsyncRemote(serverId, dockerSafeExec(command));
@@ -189,7 +197,7 @@ export const cleanupContainers = async (serverId?: string) => {
export const cleanupImages = async (serverId?: string) => {
try {
const command = "docker image prune --all --force";
const command = cleanupCommands.images;
if (serverId) {
await execAsyncRemote(serverId, dockerSafeExec(command));
@@ -203,7 +211,7 @@ export const cleanupImages = async (serverId?: string) => {
export const cleanupVolumes = async (serverId?: string) => {
try {
const command = "docker volume prune --all --force";
const command = cleanupCommands.volumes;
if (serverId) {
await execAsyncRemote(serverId, dockerSafeExec(command));
@@ -219,7 +227,7 @@ export const cleanupVolumes = async (serverId?: string) => {
export const cleanupBuilders = async (serverId?: string) => {
try {
const command = "docker builder prune --all --force";
const command = cleanupCommands.builders;
if (serverId) {
await execAsyncRemote(serverId, dockerSafeExec(command));
@@ -235,7 +243,7 @@ export const cleanupBuilders = async (serverId?: string) => {
export const cleanupSystem = async (serverId?: string) => {
try {
const command = "docker system prune --all --force";
const command = cleanupCommands.system;
if (serverId) {
await execAsyncRemote(serverId, dockerSafeExec(command));
@@ -256,6 +264,34 @@ export const cleanupAll = async (serverId?: string) => {
await cleanupSystem(serverId);
};
export const cleanupAllBackground = async (serverId?: string) => {
Promise.allSettled(
Object.values(cleanupCommands).map(async (command) => {
try {
if (serverId) {
await execAsyncRemote(serverId, dockerSafeExec(command));
} else {
await execAsync(dockerSafeExec(command));
}
} catch (error) {}
}),
)
.then((results) => {
const failed = results.filter((r) => r.status === "rejected");
if (failed.length > 0) {
console.error(`Docker cleanup: ${failed.length} operations failed`);
} else {
console.log("Docker cleanup completed successfully");
}
})
.catch((error) => console.error("Error in cleanup:", error));
return {
status: "scheduled",
message: "Docker cleanup has been initiated in the background",
};
};
export const startService = async (appName: string) => {
try {
await execAsync(`docker service scale ${appName}=1 `);