1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-28 00:06:53 +01:00

fix: prevent concurrent queries from running out of transaction (#5412)

This commit is contained in:
Mateusz Kwasniewski 2023-11-24 11:11:26 +01:00 committed by GitHub
parent aa8347eb7a
commit ce382a4bf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 1 deletions

View File

@ -52,6 +52,7 @@ import { FeatureNameCheckResultWithFeaturePattern } from '../feature-toggle/feat
import { IDependentFeaturesReadModel } from '../dependent-features/dependent-features-read-model-type'; import { IDependentFeaturesReadModel } from '../dependent-features/dependent-features-read-model-type';
import groupBy from 'lodash.groupby'; import groupBy from 'lodash.groupby';
import { ISegmentService } from '../../segments/segment-service-interface'; import { ISegmentService } from '../../segments/segment-service-interface';
import { allSettledWithRejection } from '../../util/allSettledWithRejection';
export type IImportService = { export type IImportService = {
validate( validate(
@ -252,7 +253,7 @@ export default class ExportImportService
user: IUser, user: IUser,
mode = 'regular' as Mode, mode = 'regular' as Mode,
): Promise<void> { ): Promise<void> {
await Promise.all([ await allSettledWithRejection([
this.verifyStrategies(dto), this.verifyStrategies(dto),
this.verifyContextFields(dto), this.verifyContextFields(dto),
this.importPermissionsService.verifyPermissions(dto, user, mode), this.importPermissionsService.verifyPermissions(dto, user, mode),

View File

@ -0,0 +1,47 @@
import { allSettledWithRejection } from './allSettledWithRejection';
describe('allSettledWithRejection', () => {
it('should resolve if all promises resolve', async () => {
const promises = [
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3),
];
await expect(allSettledWithRejection(promises)).resolves.toEqual([
1, 2, 3,
]);
});
it('should reject with the reason of the first rejected promise', async () => {
const error = new Error('First rejection');
const promises = [
Promise.reject(error),
Promise.resolve(1),
Promise.resolve(2),
];
await expect(allSettledWithRejection(promises)).rejects.toEqual(error);
});
it('should reject with the reason of the first rejected promise, even with multiple rejections', async () => {
const firstError = new Error('First rejection');
const secondError = new Error('Second rejection');
const promises = [
Promise.reject(firstError),
Promise.reject(secondError),
Promise.resolve(1),
];
await expect(allSettledWithRejection(promises)).rejects.toEqual(
firstError,
);
});
it('should reject with the reason of the first rejected promise in mixed scenarios', async () => {
const error = new Error('Rejection');
const promises = [
Promise.resolve(1),
Promise.reject(error),
Promise.resolve(2),
];
await expect(allSettledWithRejection(promises)).rejects.toEqual(error);
});
});

View File

@ -0,0 +1,16 @@
export const allSettledWithRejection = (
promises: Promise<any>[],
): Promise<any[]> =>
new Promise((resolve, reject) => {
Promise.allSettled(promises).then((results) => {
for (const result of results) {
if (result.status === 'rejected') {
reject(result.reason);
return;
}
}
resolve(
results.map((r) => (r as PromiseFulfilledResult<any>).value),
);
});
});