backend: Refactored room GC using bulk delete rooom method for gracefully delete the expired rooms
This commit is contained in:
parent
7ca385968d
commit
913aa44278
@ -159,11 +159,13 @@ export class RoomService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a room by its ID.
|
* Deletes multiple rooms in bulk, with the option to force delete or gracefully handle rooms with active participants.
|
||||||
|
* For rooms with participants, when `forceDelete` is false, the method performs a "graceful deletion"
|
||||||
|
* by marking the room as deleted without disrupting active sessions.
|
||||||
*
|
*
|
||||||
* @param roomId - The unique identifier of the room to delete.
|
* @param roomIds - Array of room identifiers to be deleted
|
||||||
* @param forceDelete - Whether to force delete the room even if it has participants.
|
* @param forceDelete - If true, deletes rooms even if they have active participants.
|
||||||
* @returns A promise that resolves to an object containing the deleted and marked rooms.
|
* If false, rooms with participants will be marked for deletion instead of being deleted immediately.
|
||||||
*/
|
*/
|
||||||
async bulkDeleteRooms(
|
async bulkDeleteRooms(
|
||||||
roomIds: string[],
|
roomIds: string[],
|
||||||
@ -187,10 +189,7 @@ export class RoomService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose(`Room ${roomId} has participants. Marking as deleted (graceful deletion).`);
|
this.logger.verbose(`Room ${roomId} has participants. Marking as deleted (graceful deletion).`);
|
||||||
// Mark room as deleted
|
await this.markRoomAsDeleted(roomId);
|
||||||
const room = await this.storageService.getMeetRoom(roomId);
|
|
||||||
room.markedForDeletion = true;
|
|
||||||
await this.storageService.saveMeetRoom(room);
|
|
||||||
return { roomId, status: 'marked' } as const;
|
return { roomId, status: 'marked' } as const;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -222,6 +221,19 @@ export class RoomService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks a room as deleted in the storage system.
|
||||||
|
*
|
||||||
|
* @param roomId - The unique identifier of the room to mark for deletion
|
||||||
|
* @returns A promise that resolves when the room has been successfully marked as deleted
|
||||||
|
* @throws May throw an error if the room cannot be found or if saving fails
|
||||||
|
*/
|
||||||
|
protected async markRoomAsDeleted(roomId: string): Promise<void> {
|
||||||
|
const room = await this.storageService.getMeetRoom(roomId);
|
||||||
|
room.markedForDeletion = true;
|
||||||
|
await this.storageService.saveMeetRoom(room);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a secret against a room's moderator and publisher secrets and returns the corresponding role.
|
* Validates a secret against a room's moderator and publisher secrets and returns the corresponding role.
|
||||||
*
|
*
|
||||||
@ -290,52 +302,21 @@ export class RoomService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes OpenVidu expired rooms and consequently LiveKit rooms.
|
* Gracefully deletes expired rooms.
|
||||||
*
|
*
|
||||||
* This method delete the rooms that have an expiration date earlier than the current time.
|
* This method checks for rooms that have an auto-deletion date in the past and deletes them.
|
||||||
*
|
* It also marks rooms as deleted if they have participants.
|
||||||
* @returns {Promise<void>} A promise that resolves when the deletion process is complete.
|
|
||||||
**/
|
|
||||||
protected async deleteExpiredRooms(): Promise<void> {
|
|
||||||
try {
|
|
||||||
const ovExpiredRooms = await this.deleteExpiredMeetRooms();
|
|
||||||
|
|
||||||
if (ovExpiredRooms.length === 0) return;
|
|
||||||
|
|
||||||
const livekitResults = await Promise.allSettled(
|
|
||||||
ovExpiredRooms.map((roomId) => this.livekitService.deleteRoom(roomId))
|
|
||||||
);
|
|
||||||
|
|
||||||
const successfulRooms: string[] = [];
|
|
||||||
|
|
||||||
livekitResults.forEach((result, index) => {
|
|
||||||
if (result.status === 'fulfilled') {
|
|
||||||
successfulRooms.push(ovExpiredRooms[index]);
|
|
||||||
} else {
|
|
||||||
this.logger.error(`Failed to delete OpenVidu room "${ovExpiredRooms[index]}": ${result.reason}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose(
|
|
||||||
`Successfully deleted ${successfulRooms.length} expired rooms: ${successfulRooms.join(', ')}`
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error('Error deleting expired rooms:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes expired Meet rooms by iterating through all paged results.
|
|
||||||
*
|
|
||||||
* @returns A promise that resolves with an array of room IDs that were successfully deleted.
|
|
||||||
*/
|
*/
|
||||||
protected async deleteExpiredMeetRooms(): Promise<string[]> {
|
protected async deleteExpiredRooms(): Promise<void> {
|
||||||
const now = Date.now();
|
|
||||||
this.logger.verbose(`Checking Meet expired rooms at ${new Date(now).toISOString()}`);
|
|
||||||
let nextPageToken: string | undefined;
|
let nextPageToken: string | undefined;
|
||||||
const deletedRooms: string[] = [];
|
const deletedRooms: string[] = [];
|
||||||
|
const markedAsDeletedRooms: string[] = [];
|
||||||
|
this.logger.verbose(`Checking expired rooms at ${new Date(Date.now()).toISOString()}`);
|
||||||
|
|
||||||
|
try {
|
||||||
do {
|
do {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
const { rooms, nextPageToken: token } = await this.getAllMeetRooms({ maxItems: 100, nextPageToken });
|
const { rooms, nextPageToken: token } = await this.getAllMeetRooms({ maxItems: 100, nextPageToken });
|
||||||
nextPageToken = token;
|
nextPageToken = token;
|
||||||
|
|
||||||
@ -345,14 +326,20 @@ export class RoomService {
|
|||||||
|
|
||||||
if (expiredRoomIds.length > 0) {
|
if (expiredRoomIds.length > 0) {
|
||||||
this.logger.verbose(
|
this.logger.verbose(
|
||||||
`Deleting ${expiredRoomIds.length} expired Meet rooms: ${expiredRoomIds.join(', ')}`
|
`Trying to delete ${expiredRoomIds.length} expired Meet rooms: ${expiredRoomIds.join(', ')}`
|
||||||
);
|
);
|
||||||
// const deletedOnPage = await this.deleteMeetRooms(expiredRooms);
|
|
||||||
await this.storageService.deleteMeetRooms(expiredRoomIds);
|
const { deleted, markedAsDeleted } = await this.bulkDeleteRooms(expiredRoomIds, false);
|
||||||
deletedRooms.push(...expiredRoomIds);
|
|
||||||
|
deletedRooms.push(...deleted);
|
||||||
|
markedAsDeletedRooms.push(...markedAsDeleted);
|
||||||
}
|
}
|
||||||
} while (nextPageToken);
|
} while (nextPageToken);
|
||||||
|
|
||||||
return deletedRooms;
|
this.logger.verbose(`Successfully deleted ${deletedRooms.length} expired rooms}`);
|
||||||
|
this.logger.verbose(`Marked as deleted ${markedAsDeletedRooms.length} expired rooms}`);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Error deleting expired rooms:', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user