diff --git a/server/src/cores/storage.core.ts b/server/src/cores/storage.core.ts index 5861c31ff8..4f386a51ef 100644 --- a/server/src/cores/storage.core.ts +++ b/server/src/cores/storage.core.ts @@ -254,7 +254,7 @@ export class StorageCore { this.logger.warn(`Unable to complete move. File size mismatch: ${newPathSize} !== ${oldPathSize}`); return false; } - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: true }); if (assetInfo && config.storageTemplate.hashVerificationEnabled) { const { checksum } = assetInfo; const newChecksum = await this.cryptoRepository.hashFile(newPath); diff --git a/server/src/cores/system-config.core.ts b/server/src/cores/system-config.core.ts index b03fe482c3..10fdb45637 100644 --- a/server/src/cores/system-config.core.ts +++ b/server/src/cores/system-config.core.ts @@ -42,8 +42,8 @@ export class SystemConfigCore { instance = null; } - async getConfig(force = false): Promise { - if (force || !this.config) { + async getConfig({ withCache }: { withCache: boolean }): Promise { + if (!withCache || !this.config) { const lastUpdated = this.lastUpdated; await this.asyncLock.acquire(DatabaseLock[DatabaseLock.GetSystemConfig], async () => { if (lastUpdated === this.lastUpdated) { @@ -74,13 +74,13 @@ export class SystemConfigCore { await this.repository.set(SystemMetadataKey.SYSTEM_CONFIG, partialConfig); - const config = await this.getConfig(true); + const config = await this.getConfig({ withCache: false }); this.config$.next(config); return config; } async refreshConfig() { - const newConfig = await this.getConfig(true); + const newConfig = await this.getConfig({ withCache: false }); this.config$.next(newConfig); } diff --git a/server/src/services/asset.service.ts b/server/src/services/asset.service.ts index e48de8c0c1..da333a9449 100644 --- a/server/src/services/asset.service.ts +++ b/server/src/services/asset.service.ts @@ -245,7 +245,7 @@ export class AssetService { } async handleAssetDeletionCheck(): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); const trashedDays = config.trash.enabled ? config.trash.days : 0; const trashedBefore = DateTime.now() .minus(Duration.fromObject({ days: trashedDays })) diff --git a/server/src/services/auth.service.ts b/server/src/services/auth.service.ts index 304be49f27..0f2add4337 100644 --- a/server/src/services/auth.service.ts +++ b/server/src/services/auth.service.ts @@ -77,7 +77,7 @@ export class AuthService { } async login(dto: LoginCredentialDto, details: LoginDetails) { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); if (!config.passwordLogin.enabled) { throw new UnauthorizedException('Password login has been disabled'); } @@ -174,7 +174,7 @@ export class AuthService { } async authorize(dto: OAuthConfigDto): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); if (!config.oauth.enabled) { throw new BadRequestException('OAuth is not enabled'); } @@ -190,7 +190,7 @@ export class AuthService { } async callback(dto: OAuthCallbackDto, loginDetails: LoginDetails) { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); const profile = await this.getOAuthProfile(config, dto.url); this.logger.debug(`Logging in with OAuth: ${JSON.stringify(profile)}`); let user = await this.userRepository.getByOAuthId(profile.sub); @@ -242,7 +242,7 @@ export class AuthService { } async link(auth: AuthDto, dto: OAuthCallbackDto): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); const { sub: oauthId } = await this.getOAuthProfile(config, dto.url); const duplicate = await this.userRepository.getByOAuthId(oauthId); if (duplicate && duplicate.id !== auth.user.id) { @@ -264,7 +264,7 @@ export class AuthService { return LOGIN_URL; } - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); if (!config.oauth.enabled) { return LOGIN_URL; } diff --git a/server/src/services/cli.service.ts b/server/src/services/cli.service.ts index f676d43e89..1c25c306b6 100644 --- a/server/src/services/cli.service.ts +++ b/server/src/services/cli.service.ts @@ -42,25 +42,25 @@ export class CliService { } async disablePasswordLogin(): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); config.passwordLogin.enabled = false; await this.configCore.updateConfig(config); } async enablePasswordLogin(): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); config.passwordLogin.enabled = true; await this.configCore.updateConfig(config); } async disableOAuthLogin(): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); config.oauth.enabled = false; await this.configCore.updateConfig(config); } async enableOAuthLogin(): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); config.oauth.enabled = true; await this.configCore.updateConfig(config); } diff --git a/server/src/services/duplicate.service.ts b/server/src/services/duplicate.service.ts index 6313ffa21f..ae9d101c58 100644 --- a/server/src/services/duplicate.service.ts +++ b/server/src/services/duplicate.service.ts @@ -43,7 +43,7 @@ export class DuplicateService { } async handleQueueSearchDuplicates({ force }: IBaseJob): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: false }); if (!isDuplicateDetectionEnabled(machineLearning)) { return JobStatus.SKIPPED; } @@ -64,7 +64,7 @@ export class DuplicateService { } async handleSearchDuplicates({ id }: IEntityJob): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: true }); if (!isDuplicateDetectionEnabled(machineLearning)) { return JobStatus.SKIPPED; } diff --git a/server/src/services/job.service.ts b/server/src/services/job.service.ts index dabbf4259b..25c22ebd04 100644 --- a/server/src/services/job.service.ts +++ b/server/src/services/job.service.ts @@ -150,7 +150,7 @@ export class JobService { } async init(jobHandlers: Record) { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); for (const queueName of Object.values(QueueName)) { let concurrency = 1; diff --git a/server/src/services/library.service.ts b/server/src/services/library.service.ts index 8dbf31d23d..78bacb98c9 100644 --- a/server/src/services/library.service.ts +++ b/server/src/services/library.service.ts @@ -67,7 +67,7 @@ export class LibraryService { } async init() { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); const { watch, scan } = config.library; diff --git a/server/src/services/map.service.ts b/server/src/services/map.service.ts index a08ddf0c1a..b4ade666e9 100644 --- a/server/src/services/map.service.ts +++ b/server/src/services/map.service.ts @@ -47,7 +47,7 @@ export class MapService { } async getMapStyle(theme: 'light' | 'dark') { - const { map } = await this.configCore.getConfig(); + const { map } = await this.configCore.getConfig({ withCache: false }); const styleUrl = theme === 'dark' ? map.darkStyle : map.lightStyle; if (styleUrl) { diff --git a/server/src/services/media.service.ts b/server/src/services/media.service.ts index 2ba4b34935..fc1f16a638 100644 --- a/server/src/services/media.service.ts +++ b/server/src/services/media.service.ts @@ -149,7 +149,7 @@ export class MediaService { } async handleAssetMigration({ id }: IEntityJob): Promise { - const { image } = await this.configCore.getConfig(); + const { image } = await this.configCore.getConfig({ withCache: true }); const [asset] = await this.assetRepository.getByIds([id]); if (!asset) { return JobStatus.FAILED; @@ -164,7 +164,7 @@ export class MediaService { async handleGeneratePreview({ id }: IEntityJob): Promise { const [{ image }, [asset]] = await Promise.all([ - this.configCore.getConfig(), + this.configCore.getConfig({ withCache: true }), this.assetRepository.getByIds([id], { exifInfo: true }), ]); if (!asset) { @@ -185,7 +185,7 @@ export class MediaService { } private async generateThumbnail(asset: AssetEntity, type: GeneratedImageType, format: ImageFormat) { - const { image, ffmpeg } = await this.configCore.getConfig(); + const { image, ffmpeg } = await this.configCore.getConfig({ withCache: true }); const size = type === AssetPathType.PREVIEW ? image.previewSize : image.thumbnailSize; const path = StorageCore.getImagePath(asset, type, format); this.storageCore.ensureFolders(path); @@ -237,7 +237,7 @@ export class MediaService { async handleGenerateThumbnail({ id }: IEntityJob): Promise { const [{ image }, [asset]] = await Promise.all([ - this.configCore.getConfig(), + this.configCore.getConfig({ withCache: true }), this.assetRepository.getByIds([id], { exifInfo: true }), ]); if (!asset) { @@ -318,7 +318,7 @@ export class MediaService { return JobStatus.FAILED; } - const { ffmpeg } = await this.configCore.getConfig(); + const { ffmpeg } = await this.configCore.getConfig({ withCache: true }); const target = this.getTranscodeTarget(ffmpeg, mainVideoStream, mainAudioStream); if (target === TranscodeTarget.NONE) { if (asset.encodedVideoPath) { diff --git a/server/src/services/metadata.service.ts b/server/src/services/metadata.service.ts index 5a0b363211..3c7845010f 100644 --- a/server/src/services/metadata.service.ts +++ b/server/src/services/metadata.service.ts @@ -137,7 +137,7 @@ export class MetadataService { this.subscription = this.configCore.config$.subscribe(() => handlePromiseError(this.init(), this.logger)); } - const { reverseGeocoding } = await this.configCore.getConfig(); + const { reverseGeocoding } = await this.configCore.getConfig({ withCache: false }); const { enabled } = reverseGeocoding; if (!enabled) { @@ -333,7 +333,7 @@ export class MetadataService { private async applyReverseGeocoding(asset: AssetEntity, exifData: ExifEntityWithoutGeocodeAndTypeOrm) { const { latitude, longitude } = exifData; - const { reverseGeocoding } = await this.configCore.getConfig(); + const { reverseGeocoding } = await this.configCore.getConfig({ withCache: true }); if (!reverseGeocoding.enabled || !longitude || !latitude) { return; } diff --git a/server/src/services/notification.service.ts b/server/src/services/notification.service.ts index 3aec2e04f3..acf80ce1fa 100644 --- a/server/src/services/notification.service.ts +++ b/server/src/services/notification.service.ts @@ -68,7 +68,7 @@ export class NotificationService { throw new HttpException('Failed to verify SMTP configuration', HttpStatus.BAD_REQUEST, { cause: error }); } - const { server } = await this.configCore.getConfig(); + const { server } = await this.configCore.getConfig({ withCache: false }); const { html, text } = this.notificationRepository.renderEmail({ template: EmailTemplate.TEST_EMAIL, data: { @@ -94,7 +94,7 @@ export class NotificationService { return JobStatus.SKIPPED; } - const { server } = await this.configCore.getConfig(); + const { server } = await this.configCore.getConfig({ withCache: true }); const { html, text } = this.notificationRepository.renderEmail({ template: EmailTemplate.WELCOME, data: { @@ -137,7 +137,7 @@ export class NotificationService { const attachment = await this.getAlbumThumbnailAttachment(album); - const { server } = await this.configCore.getConfig(); + const { server } = await this.configCore.getConfig({ withCache: false }); const { html, text } = this.notificationRepository.renderEmail({ template: EmailTemplate.ALBUM_INVITE, data: { @@ -179,7 +179,7 @@ export class NotificationService { const recipients = [...album.albumUsers.map((user) => user.user), owner].filter((user) => user.id !== senderId); const attachment = await this.getAlbumThumbnailAttachment(album); - const { server } = await this.configCore.getConfig(); + const { server } = await this.configCore.getConfig({ withCache: false }); for (const recipient of recipients) { const user = await this.userRepository.get(recipient.id, { withDeleted: false }); @@ -220,7 +220,7 @@ export class NotificationService { } async handleSendEmail(data: IEmailJob): Promise { - const { notifications } = await this.configCore.getConfig(); + const { notifications } = await this.configCore.getConfig({ withCache: false }); if (!notifications.smtp.enabled) { return JobStatus.SKIPPED; } diff --git a/server/src/services/person.service.ts b/server/src/services/person.service.ts index faa65974d4..6d3e4c34a1 100644 --- a/server/src/services/person.service.ts +++ b/server/src/services/person.service.ts @@ -88,7 +88,7 @@ export class PersonService { } async getAll(auth: AuthDto, dto: PersonSearchDto): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: false }); const people = await this.repository.getAllForUser(auth.user.id, { minimumFaceCount: machineLearning.facialRecognition.minFaces, withHidden: dto.withHidden || false, @@ -282,7 +282,7 @@ export class PersonService { } async handleQueueDetectFaces({ force }: IBaseJob): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: false }); if (!isFacialRecognitionEnabled(machineLearning)) { return JobStatus.SKIPPED; } @@ -313,7 +313,7 @@ export class PersonService { } async handleDetectFaces({ id }: IEntityJob): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: true }); if (!isFacialRecognitionEnabled(machineLearning)) { return JobStatus.SKIPPED; } @@ -371,7 +371,7 @@ export class PersonService { } async handleQueueRecognizeFaces({ force }: IBaseJob): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: false }); if (!isFacialRecognitionEnabled(machineLearning)) { return JobStatus.SKIPPED; } @@ -402,7 +402,7 @@ export class PersonService { } async handleRecognizeFaces({ id, deferred }: IDeferrableJob): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: true }); if (!isFacialRecognitionEnabled(machineLearning)) { return JobStatus.SKIPPED; } @@ -486,7 +486,7 @@ export class PersonService { } async handleGeneratePersonThumbnail(data: IEntityJob): Promise { - const { machineLearning, image } = await this.configCore.getConfig(); + const { machineLearning, image } = await this.configCore.getConfig({ withCache: true }); if (!isFacialRecognitionEnabled(machineLearning)) { return JobStatus.SKIPPED; } diff --git a/server/src/services/search.service.ts b/server/src/services/search.service.ts index 9213cc4290..1588662ef1 100644 --- a/server/src/services/search.service.ts +++ b/server/src/services/search.service.ts @@ -95,7 +95,7 @@ export class SearchService { } async searchSmart(auth: AuthDto, dto: SmartSearchDto): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: false }); if (!isSmartSearchEnabled(machineLearning)) { throw new BadRequestException('Smart search is not enabled'); } diff --git a/server/src/services/server-info.service.ts b/server/src/services/server-info.service.ts index 89e095ba5d..5b0831c93c 100644 --- a/server/src/services/server-info.service.ts +++ b/server/src/services/server-info.service.ts @@ -65,7 +65,7 @@ export class ServerInfoService { async getFeatures(): Promise { const { reverseGeocoding, map, machineLearning, trash, oauth, passwordLogin, notifications } = - await this.configCore.getConfig(); + await this.configCore.getConfig({ withCache: false }); return { smartSearch: isSmartSearchEnabled(machineLearning), @@ -85,12 +85,12 @@ export class ServerInfoService { } async getTheme() { - const { theme } = await this.configCore.getConfig(); + const { theme } = await this.configCore.getConfig({ withCache: false }); return theme; } async getConfig(): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); const isInitialized = await this.userRepository.hasAdmin(); const onboarding = await this.systemMetadataRepository.get(SystemMetadataKey.ADMIN_ONBOARDING); diff --git a/server/src/services/smart-info.service.ts b/server/src/services/smart-info.service.ts index 46a57c3cd0..960c90f69b 100644 --- a/server/src/services/smart-info.service.ts +++ b/server/src/services/smart-info.service.ts @@ -40,7 +40,7 @@ export class SmartInfoService { await this.jobRepository.waitForQueueCompletion(QueueName.SMART_SEARCH); - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: false }); await this.databaseRepository.withLock(DatabaseLock.CLIPDimSize, () => this.repository.init(machineLearning.clip.modelName), @@ -50,7 +50,7 @@ export class SmartInfoService { } async handleQueueEncodeClip({ force }: IBaseJob): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: false }); if (!isSmartSearchEnabled(machineLearning)) { return JobStatus.SKIPPED; } @@ -75,7 +75,7 @@ export class SmartInfoService { } async handleEncodeClip({ id }: IEntityJob): Promise { - const { machineLearning } = await this.configCore.getConfig(); + const { machineLearning } = await this.configCore.getConfig({ withCache: true }); if (!isSmartSearchEnabled(machineLearning)) { return JobStatus.SKIPPED; } diff --git a/server/src/services/storage-template.service.ts b/server/src/services/storage-template.service.ts index 945b6f4500..7c4cf738db 100644 --- a/server/src/services/storage-template.service.ts +++ b/server/src/services/storage-template.service.ts @@ -110,7 +110,7 @@ export class StorageTemplateService { } async handleMigrationSingle({ id }: IEntityJob): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: true }); const storageTemplateEnabled = config.storageTemplate.enabled; if (!storageTemplateEnabled) { return JobStatus.SKIPPED; @@ -140,7 +140,7 @@ export class StorageTemplateService { async handleMigration(): Promise { this.logger.log('Starting storage template migration'); - const { storageTemplate } = await this.configCore.getConfig(); + const { storageTemplate } = await this.configCore.getConfig({ withCache: true }); const { enabled } = storageTemplate; if (!enabled) { this.logger.log('Storage template migration disabled, skipping'); diff --git a/server/src/services/system-config.service.ts b/server/src/services/system-config.service.ts index 028a1fd323..d1e535daba 100644 --- a/server/src/services/system-config.service.ts +++ b/server/src/services/system-config.service.ts @@ -42,7 +42,7 @@ export class SystemConfigService { } async init() { - const config = await this.core.getConfig(); + const config = await this.core.getConfig({ withCache: false }); this.config$.next(config); } @@ -51,7 +51,7 @@ export class SystemConfigService { } async getConfig(): Promise { - const config = await this.core.getConfig(); + const config = await this.core.getConfig({ withCache: false }); return mapConfig(config); } @@ -71,7 +71,7 @@ export class SystemConfigService { throw new BadRequestException('Cannot update configuration while IMMICH_CONFIG_FILE is in use'); } - const oldConfig = await this.core.getConfig(); + const oldConfig = await this.core.getConfig({ withCache: false }); try { await this.eventRepository.serverSendAsync(ServerAsyncEvent.CONFIG_VALIDATE, { @@ -110,7 +110,7 @@ export class SystemConfigService { } async getCustomCss(): Promise { - const { theme } = await this.core.getConfig(); + const { theme } = await this.core.getConfig({ withCache: false }); return theme.customCss; } diff --git a/server/src/services/user.service.ts b/server/src/services/user.service.ts index 3920dbeaac..4ba19a97f8 100644 --- a/server/src/services/user.service.ts +++ b/server/src/services/user.service.ts @@ -128,7 +128,7 @@ export class UserService { async handleUserDeleteCheck(): Promise { const users = await this.userRepository.getDeletedUsers(); - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); await this.jobRepository.queueAll( users.flatMap((user) => this.isReadyForDeletion(user, config.user.deleteDelay) @@ -140,7 +140,7 @@ export class UserService { } async handleUserDelete({ id, force }: IEntityJob): Promise { - const config = await this.configCore.getConfig(); + const config = await this.configCore.getConfig({ withCache: false }); const user = await this.userRepository.get(id, { withDeleted: true }); if (!user) { return JobStatus.FAILED; diff --git a/server/src/services/version.service.ts b/server/src/services/version.service.ts index fdfe78991f..ecaa2f6f49 100644 --- a/server/src/services/version.service.ts +++ b/server/src/services/version.service.ts @@ -56,7 +56,7 @@ export class VersionService { return JobStatus.SKIPPED; } - const { newVersionCheck } = await this.configCore.getConfig(); + const { newVersionCheck } = await this.configCore.getConfig({ withCache: true }); if (!newVersionCheck.enabled) { return JobStatus.SKIPPED; }