1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-06-04 01:18:20 +02:00

feat: exclude archived features in max reporting (#7559)

This commit is contained in:
Mateusz Kwasniewski 2024-07-10 09:11:22 +02:00 committed by GitHub
parent d9ae0f3f59
commit 3fe110f155
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 66 additions and 42 deletions

View File

@ -7,12 +7,23 @@ export class FeatureStrategiesReadModel implements IFeatureStrategiesReadModel {
constructor(db: Db) { constructor(db: Db) {
this.db = db; this.db = db;
} }
private activeStrategies() {
return this.db('feature_strategies')
.leftJoin(
'features',
'features.name',
'feature_strategies.feature_name',
)
.where('features.archived_at', null);
}
async getMaxFeatureEnvironmentStrategies(): Promise<{ async getMaxFeatureEnvironmentStrategies(): Promise<{
feature: string; feature: string;
environment: string; environment: string;
count: number; count: number;
} | null> { } | null> {
const rows = await this.db('feature_strategies') const rows = await this.activeStrategies()
.select('feature_name', 'environment') .select('feature_name', 'environment')
.count('id as strategy_count') .count('id as strategy_count')
.groupBy('feature_name', 'environment') .groupBy('feature_name', 'environment')
@ -32,7 +43,7 @@ export class FeatureStrategiesReadModel implements IFeatureStrategiesReadModel {
feature: string; feature: string;
count: number; count: number;
} | null> { } | null> {
const rows = await this.db('feature_strategies') const rows = await this.activeStrategies()
.select('feature_name') .select('feature_name')
.count('id as strategy_count') .count('id as strategy_count')
.groupBy('feature_name') .groupBy('feature_name')
@ -52,7 +63,7 @@ export class FeatureStrategiesReadModel implements IFeatureStrategiesReadModel {
environment: string; environment: string;
count: number; count: number;
} | null> { } | null> {
const rows = await this.db('feature_strategies') const rows = await this.activeStrategies()
.select( .select(
'feature_name', 'feature_name',
'environment', 'environment',
@ -60,9 +71,9 @@ export class FeatureStrategiesReadModel implements IFeatureStrategiesReadModel {
"MAX(coalesce(jsonb_array_length(constraint_value->'values'), 0)) as max_values_count", "MAX(coalesce(jsonb_array_length(constraint_value->'values'), 0)) as max_values_count",
), ),
) )
.from( .crossJoin(
this.db.raw( this.db.raw(
'feature_strategies, jsonb_array_elements(constraints) AS constraint_value', `jsonb_array_elements(constraints) AS constraint_value`,
), ),
) )
.groupBy('feature_name', 'environment') .groupBy('feature_name', 'environment')
@ -77,12 +88,13 @@ export class FeatureStrategiesReadModel implements IFeatureStrategiesReadModel {
} }
: null; : null;
} }
async getMaxConstraintsPerStrategy(): Promise<{ async getMaxConstraintsPerStrategy(): Promise<{
feature: string; feature: string;
environment: string; environment: string;
count: number; count: number;
} | null> { } | null> {
const rows = await this.db('feature_strategies') const rows = await this.activeStrategies()
.select( .select(
'feature_name', 'feature_name',
'environment', 'environment',

View File

@ -5,6 +5,7 @@ import dbInit, {
} from '../../../../test/e2e/helpers/database-init'; } from '../../../../test/e2e/helpers/database-init';
import getLogger from '../../../../test/fixtures/no-logger'; import getLogger from '../../../../test/fixtures/no-logger';
import type { import type {
IConstraint,
IFeatureStrategiesReadModel, IFeatureStrategiesReadModel,
IProjectStore, IProjectStore,
IUnleashStores, IUnleashStores,
@ -294,6 +295,32 @@ describe('max metrics collection', () => {
}); });
}); });
const bigConstraint = (maxValueCount: number) => {
return {
values: Array.from({ length: maxValueCount }, (_, i) =>
i.toString(),
),
operator: 'IN',
contextName: 'appName',
} as const;
};
const strategyWithConstraints = (
feature: string,
constraint: IConstraint,
) => {
return {
strategyName: 'gradualRollout',
projectId: 'default',
environment: 'default',
featureName: feature,
constraints: [constraint],
sortOrder: 0,
parameters: {},
};
};
test('Read feature with max number of constraint values', async () => { test('Read feature with max number of constraint values', async () => {
const flagA = await featureToggleStore.create('default', { const flagA = await featureToggleStore.create('default', {
name: randomId(), name: randomId(),
@ -305,48 +332,33 @@ describe('max metrics collection', () => {
createdByUserId: 9999, createdByUserId: 9999,
}); });
const flagC = await featureToggleStore.create('default', {
name: randomId(),
createdByUserId: 9999,
});
const maxConstraintValuesBefore = const maxConstraintValuesBefore =
await featureStrategiesReadModel.getMaxConstraintValues(); await featureStrategiesReadModel.getMaxConstraintValues();
expect(maxConstraintValuesBefore).toBe(null); expect(maxConstraintValuesBefore).toBe(null);
const maxValueCount = 100; const maxValueCount = 100;
await featureStrategiesStore.createStrategyFeatureEnv({ await featureStrategiesStore.createStrategyFeatureEnv(
strategyName: 'gradualRollout', strategyWithConstraints(flagA.name, bigConstraint(maxValueCount)),
projectId: 'default', );
environment: 'default', await featureStrategiesStore.createStrategyFeatureEnv(
featureName: flagA.name, strategyWithConstraints(flagB.name, {
constraints: [ operator: 'IN',
{ contextName: 'appName',
values: ['only one'], }),
operator: 'IN', );
contextName: 'appName', await featureStrategiesStore.createStrategyFeatureEnv(
}, strategyWithConstraints(
{ flagC.name,
values: Array.from({ length: maxValueCount }, (_, i) => bigConstraint(maxValueCount + 1),
i.toString(), ),
), );
operator: 'IN',
contextName: 'appName',
},
],
sortOrder: 0, await featureToggleStore.archive(flagC.name);
parameters: {},
});
await featureStrategiesStore.createStrategyFeatureEnv({
strategyName: 'gradualRollout',
projectId: 'default',
environment: 'default',
featureName: flagB.name,
constraints: [
{
operator: 'IN',
contextName: 'appName',
},
],
sortOrder: 0,
parameters: {},
});
const maxConstraintValues = const maxConstraintValues =
await featureStrategiesReadModel.getMaxConstraintValues(); await featureStrategiesReadModel.getMaxConstraintValues();