backend: Rename setPrivateConfig to setInternalConfig for clarity; add errorRecordingStartTimeout for handling timeout scenarios

This commit is contained in:
Carlos Santos 2025-04-16 11:09:55 +02:00
parent f6532fa281
commit 524460e06a
4 changed files with 20 additions and 17 deletions

View File

@ -36,7 +36,7 @@ const INTERNAL_CONFIG = {
// This function is used to set private configuration values for testing purposes. // This function is used to set private configuration values for testing purposes.
// It allows you to override the default values defined in the INTERNAL_CONFIG object. // It allows you to override the default values defined in the INTERNAL_CONFIG object.
// This is useful for testing different scenarios without modifying the actual configuration file. // This is useful for testing different scenarios without modifying the actual configuration file.
export const setPrivateConfig = (overrides: Partial<typeof INTERNAL_CONFIG>): void => { export const setInternalConfig = (overrides: Partial<typeof INTERNAL_CONFIG>): void => {
Object.assign(INTERNAL_CONFIG, overrides); Object.assign(INTERNAL_CONFIG, overrides);
}; };

View File

@ -75,6 +75,14 @@ export const errorRecordingAlreadyStarted = (roomId: string): OpenViduMeetError
return new OpenViduMeetError('Recording Error', `The room '${roomId}' is already being recorded`, 409); return new OpenViduMeetError('Recording Error', `The room '${roomId}' is already being recorded`, 409);
}; };
export const errorRecordingStartTimeout = (roomId: string): OpenViduMeetError => {
return new OpenViduMeetError(
'Recording Error',
`Recording in room '${roomId}' timed out while starting`,
503
);
};
export const errorRoomHasNoParticipants = (roomId: string): OpenViduMeetError => { export const errorRoomHasNoParticipants = (roomId: string): OpenViduMeetError => {
return new OpenViduMeetError('Recording Error', `The room '${roomId}' has no participants`, 409); return new OpenViduMeetError('Recording Error', `The room '${roomId}' has no participants`, 409);
}; };

View File

@ -207,10 +207,10 @@ export class LivekitWebhookService {
if (recordingInfo.status === MeetRecordingStatus.ACTIVE) { if (recordingInfo.status === MeetRecordingStatus.ACTIVE) {
// Send system event for active recording with the aim of cancelling the cleanup timer // Send system event for active recording with the aim of cancelling the cleanup timer
tasks.push( tasks.push(
this.systemEventService.publishEvent(SystemEventType.RECORDING_ACTIVE, { this.systemEventService.publishEvent(
roomId, SystemEventType.RECORDING_ACTIVE,
recordingId recordingInfo as unknown as Record<string, unknown>
}) )
); );
} }

View File

@ -9,6 +9,7 @@ import {
errorRecordingCannotBeStoppedWhileStarting, errorRecordingCannotBeStoppedWhileStarting,
errorRecordingNotFound, errorRecordingNotFound,
errorRecordingNotStopped, errorRecordingNotStopped,
errorRecordingStartTimeout,
errorRoomHasNoParticipants, errorRoomHasNoParticipants,
errorRoomNotFound, errorRoomNotFound,
internalError, internalError,
@ -21,10 +22,7 @@ import { S3Service } from './s3.service.js';
import { LoggerService } from './logger.service.js'; import { LoggerService } from './logger.service.js';
import { MeetRecordingFilters, MeetRecordingInfo, MeetRecordingStatus } from '@typings-ce'; import { MeetRecordingFilters, MeetRecordingInfo, MeetRecordingStatus } from '@typings-ce';
import { RecordingHelper } from '../helpers/recording.helper.js'; import { RecordingHelper } from '../helpers/recording.helper.js';
import { import { MEET_S3_BUCKET, MEET_S3_SUBBUCKET } from '../environment.js';
MEET_S3_BUCKET,
MEET_S3_SUBBUCKET
} from '../environment.js';
import { RoomService } from './room.service.js'; import { RoomService } from './room.service.js';
import { inject, injectable } from '../config/dependency-injector.config.js'; import { inject, injectable } from '../config/dependency-injector.config.js';
import { MutexService, RedisLock } from './mutex.service.js'; import { MutexService, RedisLock } from './mutex.service.js';
@ -94,17 +92,16 @@ export class RecordingService {
callback: this.handleRecordingLockTimeout.bind(this, recordingId, roomId, reject) callback: this.handleRecordingLockTimeout.bind(this, recordingId, roomId, reject)
}); });
this.systemEventService.once(SystemEventType.RECORDING_ACTIVE, (payload: Record<string, unknown>) => { this.systemEventService.once(SystemEventType.RECORDING_ACTIVE, (info: Record<string, unknown>) => {
// This listener is triggered only for the instance that started the recording. // This listener is triggered only for the instance that started the recording.
// Check if the recording ID matches the one that was started // Check if the recording ID matches the one that was started
const isEventForCurrentRecording = const isEventForCurrentRecording = info?.recordingId === recordingId && info?.roomId === roomId;
payload?.recordingId === recordingId && payload?.roomId === roomId;
if (isEventForCurrentRecording) { if (isEventForCurrentRecording) {
this.taskSchedulerService.cancelTask(`${roomId}_recording_timeout`); this.taskSchedulerService.cancelTask(`${roomId}_recording_timeout`);
resolve(recordingInfo); resolve(info as unknown as MeetRecordingInfo);
} else { } else {
this.logger.error('Received recording active event with mismatched recording ID:', payload); this.logger.error('Received recording active event with mismatched recording ID:', info);
} }
}); });
}); });
@ -528,9 +525,7 @@ export class RecordingService {
} }
// Reject the REST request with a timeout error. // Reject the REST request with a timeout error.
rejectRequest( rejectRequest(errorRecordingStartTimeout(roomId));
new Error(`Timeout waiting for '${SystemEventType.RECORDING_ACTIVE}' event in room '${roomId}'`)
);
} }
} }