1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

fix(server): make system config core singleton (#4392)

* make system config core singleton

* refactor

* fix tests

* chore: fix tests

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Daniel Dietzler 2023-10-09 02:51:03 +02:00 committed by GitHub
parent 66ccf298ba
commit 0243570c0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 33 additions and 19 deletions

View File

@ -77,7 +77,7 @@ export class AssetService {
) {
this.access = new AccessCore(accessRepository);
this.storageCore = new StorageCore(storageRepository);
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
}
canUploadFile({ authUser, fieldName, file }: UploadRequest): true {

View File

@ -71,7 +71,7 @@ export class AuthService {
@Inject(ISharedLinkRepository) private sharedLinkRepository: ISharedLinkRepository,
@Inject(IKeyRepository) private keyRepository: IKeyRepository,
) {
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
this.userCore = new UserCore(userRepository, libraryRepository, cryptoRepository);
custom.setHttpOptionsDefaults({ timeout: 30000 });

View File

@ -223,8 +223,7 @@ describe(JobService.name, () => {
it('should subscribe to config changes', async () => {
await sut.registerHandlers(makeMockHandlers(false));
const configCore = new SystemConfigCore(newSystemConfigRepositoryMock());
configCore.config$.next({
SystemConfigCore.create(newSystemConfigRepositoryMock(false)).config$.next({
job: {
[QueueName.BACKGROUND_TASK]: { concurrency: 10 },
[QueueName.CLIP_ENCODING]: { concurrency: 10 },

View File

@ -21,7 +21,7 @@ export class JobService {
@Inject(ISystemConfigRepository) configRepository: ISystemConfigRepository,
@Inject(IPersonRepository) private personRepository: IPersonRepository,
) {
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
}
async handleCommand(queueName: QueueName, dto: JobCommandDto): Promise<JobStatusDto> {

View File

@ -24,7 +24,7 @@ export class MediaService {
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
@Inject(ISystemConfigRepository) configRepository: ISystemConfigRepository,
) {
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
this.storageCore = new StorageCore(this.storageRepository);
}

View File

@ -67,7 +67,7 @@ export class MetadataService {
@Inject(ISystemConfigRepository) configRepository: ISystemConfigRepository,
) {
this.storageCore = new StorageCore(storageRepository);
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
this.configCore.config$.subscribe(() => this.init());
}

View File

@ -49,7 +49,7 @@ export class PersonService {
) {
this.access = new AccessCore(accessRepository);
this.storageCore = new StorageCore(storageRepository);
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
}
async getAll(authUser: AuthUserDto, dto: PersonSearchDto): Promise<PeopleResponseDto> {

View File

@ -57,7 +57,7 @@ export class SearchService {
@Inject(ISearchRepository) private searchRepository: ISearchRepository,
@Inject(ISystemConfigRepository) configRepository: ISystemConfigRepository,
) {
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
}
teardown() {

View File

@ -24,7 +24,7 @@ export class ServerInfoService {
@Inject(IUserRepository) private userRepository: IUserRepository,
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
) {
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
this.storageCore = new StorageCore(storageRepository);
}

View File

@ -17,7 +17,7 @@ export class SmartInfoService {
@Inject(ISmartInfoRepository) private repository: ISmartInfoRepository,
@Inject(IMachineLearningRepository) private machineLearning: IMachineLearningRepository,
) {
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
}
async handleQueueObjectTagging({ force }: IBaseJob) {

View File

@ -42,7 +42,7 @@ export class StorageTemplateService {
@Inject(IUserRepository) private userRepository: IUserRepository,
) {
this.storageTemplate = this.compile(config.storageTemplate.template);
this.configCore = new SystemConfigCore(configRepository);
this.configCore = SystemConfigCore.create(configRepository);
this.configCore.addValidator((config) => this.validate(config));
this.configCore.config$.subscribe((config) => this.onConfig(config));
this.storageCore = new StorageCore(storageRepository);

View File

@ -134,7 +134,7 @@ export enum FeatureFlag {
export type FeatureFlags = Record<FeatureFlag, boolean>;
const singleton = new Subject<SystemConfig>();
let instance: SystemConfigCore | null;
@Injectable()
export class SystemConfigCore {
@ -142,9 +142,20 @@ export class SystemConfigCore {
private validators: SystemConfigValidator[] = [];
private configCache: SystemConfig | null = null;
public config$ = singleton;
public config$ = new Subject<SystemConfig>();
constructor(private repository: ISystemConfigRepository) {}
private constructor(private repository: ISystemConfigRepository) {}
static create(repository: ISystemConfigRepository) {
if (!instance) {
instance = new SystemConfigCore(repository);
}
return instance;
}
static reset() {
instance = null;
}
async requireFeature(feature: FeatureFlag) {
const hasFeature = await this.hasFeature(feature);

View File

@ -13,7 +13,7 @@ import {
} from '@app/infra/entities';
import { BadRequestException } from '@nestjs/common';
import { newCommunicationRepositoryMock, newJobRepositoryMock, newSystemConfigRepositoryMock } from '@test';
import { ICommunicationRepository } from '..';
import { ICommunicationRepository } from '../communication';
import { IJobRepository, JobName, QueueName } from '../job';
import { SystemConfigValidator, defaults } from './system-config.core';
import { ISystemConfigRepository } from './system-config.repository';

View File

@ -24,7 +24,7 @@ export class SystemConfigService {
@Inject(ICommunicationRepository) private communicationRepository: ICommunicationRepository,
@Inject(IJobRepository) private jobRepository: IJobRepository,
) {
this.core = new SystemConfigCore(repository);
this.core = SystemConfigCore.create(repository);
}
get config$() {

View File

@ -1,6 +1,10 @@
import { ISystemConfigRepository } from '@app/domain';
import { ISystemConfigRepository, SystemConfigCore } from '@app/domain';
export const newSystemConfigRepositoryMock = (reset = true): jest.Mocked<ISystemConfigRepository> => {
if (reset) {
SystemConfigCore.reset();
}
export const newSystemConfigRepositoryMock = (): jest.Mocked<ISystemConfigRepository> => {
return {
load: jest.fn().mockResolvedValue([]),
readFile: jest.fn(),