fix async preference bug
This commit is contained in:
parent
65cff6f276
commit
5f81a577f1
|
@ -30,7 +30,6 @@ export class PreferenceDefaultsService {
|
|||
if (envSecret) {
|
||||
return envSecret;
|
||||
} else {
|
||||
console.trace(`what`);
|
||||
this.logger.warn(
|
||||
'Since no JWT secret was provided, a random one will be generated and saved',
|
||||
);
|
||||
|
|
|
@ -3,16 +3,20 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||
import {
|
||||
DecodedSysPref,
|
||||
PrefValueType,
|
||||
PrefValueTypeStrings
|
||||
PrefValueTypeStrings,
|
||||
} from 'picsur-shared/dist/dto/preferences.dto';
|
||||
import { SysPreference } from 'picsur-shared/dist/dto/syspreferences.dto';
|
||||
import { AsyncFailable, Fail, HasFailed } from 'picsur-shared/dist/types';
|
||||
import { Repository } from 'typeorm';
|
||||
import {
|
||||
SysPreferenceList,
|
||||
SysPreferenceValueTypes
|
||||
SysPreferenceValueTypes,
|
||||
} from '../../models/dto/syspreferences.dto';
|
||||
import { ESysPreferenceBackend, ESysPreferenceSchema } from '../../models/entities/syspreference.entity';
|
||||
import {
|
||||
ESysPreferenceBackend,
|
||||
ESysPreferenceSchema,
|
||||
} from '../../models/entities/syspreference.entity';
|
||||
import { FallBackMutex } from '../../models/util/FallBackMutex';
|
||||
import { PreferenceCommonService } from './preferencecommon.service';
|
||||
import { PreferenceDefaultsService } from './preferencedefaults.service';
|
||||
|
||||
|
@ -57,29 +61,25 @@ export class SysPreferenceService {
|
|||
|
||||
public async getPreference(key: string): AsyncFailable<DecodedSysPref> {
|
||||
// Validate
|
||||
let validatedKey = this.prefCommon.validatePrefKey(
|
||||
key,
|
||||
SysPreference,
|
||||
);
|
||||
let validatedKey = this.prefCommon.validatePrefKey(key, SysPreference);
|
||||
if (HasFailed(validatedKey)) return validatedKey;
|
||||
|
||||
// Fetch
|
||||
let foundSysPreference: ESysPreferenceBackend | null;
|
||||
let foundSysPreference: ESysPreferenceBackend;
|
||||
try {
|
||||
foundSysPreference = await this.sysPreferenceRepository.findOne({
|
||||
where: { key: validatedKey },
|
||||
cache: 60000,
|
||||
});
|
||||
foundSysPreference = await FallBackMutex(
|
||||
'fetchSysPrefrence',
|
||||
() =>
|
||||
this.sysPreferenceRepository.findOne({
|
||||
where: { key: validatedKey as SysPreference },
|
||||
cache: 60000,
|
||||
}),
|
||||
() => this.saveDefault(validatedKey as SysPreference),
|
||||
);
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
return Fail('Could not get preference');
|
||||
}
|
||||
|
||||
// Fallback
|
||||
if (!foundSysPreference) {
|
||||
return this.saveDefault(validatedKey);
|
||||
}
|
||||
|
||||
// Validate
|
||||
const result = ESysPreferenceSchema.safeParse(foundSysPreference);
|
||||
if (!result.success) {
|
||||
|
|
|
@ -3,19 +3,20 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||
import {
|
||||
DecodedUsrPref,
|
||||
PrefValueType,
|
||||
PrefValueTypeStrings
|
||||
PrefValueTypeStrings,
|
||||
} from 'picsur-shared/dist/dto/preferences.dto';
|
||||
import { UsrPreference } from 'picsur-shared/dist/dto/usrpreferences.dto';
|
||||
import { AsyncFailable, Fail, HasFailed } from 'picsur-shared/dist/types';
|
||||
import { Repository } from 'typeorm';
|
||||
import {
|
||||
UsrPreferenceList,
|
||||
UsrPreferenceValueTypes
|
||||
UsrPreferenceValueTypes,
|
||||
} from '../../models/dto/usrpreferences.dto';
|
||||
import {
|
||||
EUsrPreferenceBackend,
|
||||
EUsrPreferenceSchema
|
||||
EUsrPreferenceSchema,
|
||||
} from '../../models/entities/usrpreference.entity';
|
||||
import { FallBackMutex } from '../../models/util/FallBackMutex';
|
||||
import { PreferenceCommonService } from './preferencecommon.service';
|
||||
import { PreferenceDefaultsService } from './preferencedefaults.service';
|
||||
|
||||
|
@ -68,23 +69,22 @@ export class UsrPreferenceService {
|
|||
let validatedKey = this.prefCommon.validatePrefKey(key, UsrPreference);
|
||||
if (HasFailed(validatedKey)) return validatedKey;
|
||||
|
||||
// Fetch
|
||||
let foundUsrPreference: EUsrPreferenceBackend | null;
|
||||
let foundUsrPreference: EUsrPreferenceBackend;
|
||||
try {
|
||||
foundUsrPreference = await this.usrPreferenceRepository.findOne({
|
||||
where: { key: validatedKey, userId: userid },
|
||||
cache: 60000,
|
||||
});
|
||||
foundUsrPreference = await FallBackMutex(
|
||||
'fetchUsrPrefrence',
|
||||
() =>
|
||||
this.usrPreferenceRepository.findOne({
|
||||
where: { key: validatedKey as UsrPreference, userId: userid },
|
||||
cache: 60000,
|
||||
}),
|
||||
() => this.saveDefault(userid, validatedKey as UsrPreference),
|
||||
);
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
return Fail('Could not get preference');
|
||||
}
|
||||
|
||||
// Fallback
|
||||
if (!foundUsrPreference) {
|
||||
return this.saveDefault(userid, validatedKey);
|
||||
}
|
||||
|
||||
// Validate
|
||||
const result = EUsrPreferenceSchema.safeParse(foundUsrPreference);
|
||||
if (!result.success) {
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
import { AsyncFailable, HasSuccess } from 'picsur-shared/dist/types';
|
||||
/*
|
||||
This function is necessary to make sure that a default isnt generated multiple times at the same time.
|
||||
Doing that will cause errors.
|
||||
|
||||
An example is the jwt secret value, its value is requested aroun 3 times at the same time while starting.
|
||||
So when the program was started for the first time, each request returned a different secret.
|
||||
|
||||
This function will first try and see if its first function returns a value, if it does, it will return that value.
|
||||
If not it will execute a fallback function, which usually is a function that populates a default value.
|
||||
After that is done it will retry the first function again.
|
||||
*/
|
||||
|
||||
const fallBackMap: Record<string, Promise<unknown>> = {};
|
||||
|
||||
export async function FallBackMutex<
|
||||
MF extends () => AsyncFailable<O>,
|
||||
FF extends () => AsyncFailable<unknown>,
|
||||
MF extends () => Promise<O | null | undefined>,
|
||||
FF extends () => Promise<unknown>,
|
||||
O,
|
||||
>(key: string, mainFunc: MF, fallBackFunc: FF): AsyncFailable<O> {
|
||||
>(key: string, mainFunc: MF, fallBackFunc: FF): Promise<O> {
|
||||
const try_it = await mainFunc();
|
||||
if (HasSuccess(try_it)) return try_it;
|
||||
if (try_it !== undefined && try_it !== null) return try_it;
|
||||
|
||||
if (fallBackMap[key] !== undefined) {
|
||||
await fallBackMap[key];
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
Get,
|
||||
InternalServerErrorException,
|
||||
Logger,
|
||||
Post
|
||||
Post,
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
GetSpecialUsersResponse,
|
||||
|
@ -17,7 +17,7 @@ import {
|
|||
UserListRequest,
|
||||
UserListResponse,
|
||||
UserUpdateRequest,
|
||||
UserUpdateResponse
|
||||
UserUpdateResponse,
|
||||
} from 'picsur-shared/dist/dto/api/usermanage.dto';
|
||||
import { HasFailed } from 'picsur-shared/dist/types';
|
||||
import { UsersService } from '../../../collections/userdb/userdb.service';
|
||||
|
@ -27,7 +27,7 @@ import { Permission } from '../../../models/dto/permissions.dto';
|
|||
import {
|
||||
ImmutableUsersList,
|
||||
LockedLoginUsersList,
|
||||
UndeletableUsersList
|
||||
UndeletableUsersList,
|
||||
} from '../../../models/dto/specialusers.dto';
|
||||
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
|
||||
|
||||
|
|
Loading…
Reference in a new issue