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

fix: improve health rating job performance (#9761)

This commit is contained in:
Mateusz Kwasniewski 2025-04-15 14:20:26 +02:00 committed by GitHub
parent 3fd74262bb
commit 6396da3e77
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 15 deletions

View File

@ -10,6 +10,9 @@ import {
calculateProjectHealth,
calculateProjectHealthRating,
} from '../domain/project-health/project-health';
import { batchExecute } from '../util';
import metricsHelper from '../util/metrics-helper';
import { FUNCTION_TIME } from '../metric-events';
export default class ProjectHealthService {
private logger: Logger;
@ -22,7 +25,9 @@ export default class ProjectHealthService {
private projectService: ProjectService;
calculateHealthRating: (project: IProject) => Promise<number>;
calculateHealthRating: (project: Pick<IProject, 'id'>) => Promise<number>;
private timer: Function;
constructor(
{
@ -33,7 +38,7 @@ export default class ProjectHealthService {
IUnleashStores,
'projectStore' | 'featureTypeStore' | 'featureToggleStore'
>,
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
{ getLogger, eventBus }: Pick<IUnleashConfig, 'getLogger' | 'eventBus'>,
projectService: ProjectService,
) {
this.logger = getLogger('services/project-health-service.ts');
@ -46,6 +51,11 @@ export default class ProjectHealthService {
this.featureTypeStore,
this.featureToggleStore,
);
this.timer = (functionName: string) =>
metricsHelper.wrapTimer(eventBus, FUNCTION_TIME, {
className: 'ProjectHealthService',
functionName,
});
}
async getProjectHealthReport(
@ -70,17 +80,21 @@ export default class ProjectHealthService {
};
}
async setHealthRating(): Promise<void> {
async setHealthRating(batchSize = 1): Promise<void> {
const projects = await this.projectStore.getAll();
await Promise.all(
projects.map(async (project) => {
const newHealth = await this.calculateHealthRating(project);
await this.projectStore.updateHealth({
id: project.id,
health: newHealth,
});
}),
void batchExecute(projects, batchSize, 5000, (project) =>
this.setProjectHealthRating(project.id),
);
}
async setProjectHealthRating(projectId: string): Promise<void> {
const stopTimer = this.timer('setProjectHealthRating');
const newHealth = await this.calculateHealthRating({ id: projectId });
await this.projectStore.updateHealth({
id: projectId,
health: newHealth,
});
stopTimer();
}
}

View File

@ -112,7 +112,7 @@ test('Health rating endpoint yields stale, potentially stale and active count on
stale: true,
})
.expect(201);
await app.services.projectHealthService.setHealthRating();
await app.services.projectHealthService.setProjectHealthRating(project.id);
await app.request
.get(`/api/admin/projects/${project.id}/health-report`)
.expect(200)
@ -177,7 +177,7 @@ test('Health rating endpoint does not include archived toggles when calculating
})
.expect(201);
await app.services.projectHealthService.setHealthRating();
await app.services.projectHealthService.setProjectHealthRating(project.id);
await app.request
.get(`/api/admin/projects/${project.id}/health-report`)
.expect(200)
@ -232,7 +232,7 @@ test('Health rating endpoint correctly handles potentially stale toggles', async
createdAt: new Date(2019, 5, 1),
})
.expect(201);
await app.services.projectHealthService.setHealthRating();
await app.services.projectHealthService.setProjectHealthRating(project.id);
await app.request
.get(`/api/admin/projects/${project.id}/health-report`)
.expect(200)
@ -339,7 +339,7 @@ test('Sorts environments correctly if sort order is equal', async () => {
});
test('Update update_at when setHealth runs', async () => {
await app.services.projectHealthService.setHealthRating();
await app.services.projectHealthService.setProjectHealthRating('default');
await app.request
.get('/api/admin/projects/default/health-report')
.expect(200)