mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: improve status job performance (#9755)
This commit is contained in:
		
							parent
							
								
									fc40a4b4d8
								
							
						
					
					
						commit
						0efa2585fe
					
				@ -117,6 +117,7 @@ class ProjectStatsStore implements IProjectStatsStore {
 | 
				
			|||||||
    async getTimeToProdDates(
 | 
					    async getTimeToProdDates(
 | 
				
			||||||
        projectId: string,
 | 
					        projectId: string,
 | 
				
			||||||
    ): Promise<ICreateEnabledDates[]> {
 | 
					    ): Promise<ICreateEnabledDates[]> {
 | 
				
			||||||
 | 
					        const stopTimer = this.timer('getTimeToProdDates');
 | 
				
			||||||
        const result = await this.db
 | 
					        const result = await this.db
 | 
				
			||||||
            .select('events.feature_name')
 | 
					            .select('events.feature_name')
 | 
				
			||||||
            // select only first enabled event, distinct works with orderBy
 | 
					            // select only first enabled event, distinct works with orderBy
 | 
				
			||||||
@ -143,6 +144,7 @@ class ProjectStatsStore implements IProjectStatsStore {
 | 
				
			|||||||
            .orderBy('events.feature_name')
 | 
					            .orderBy('events.feature_name')
 | 
				
			||||||
            // first enabled event
 | 
					            // first enabled event
 | 
				
			||||||
            .orderBy('events.created_at', 'asc');
 | 
					            .orderBy('events.created_at', 'asc');
 | 
				
			||||||
 | 
					        stopTimer();
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -89,6 +89,9 @@ import type EventEmitter from 'events';
 | 
				
			|||||||
import type { ApiTokenService } from '../../services/api-token-service';
 | 
					import type { ApiTokenService } from '../../services/api-token-service';
 | 
				
			||||||
import type { ProjectForUi } from './project-read-model-type';
 | 
					import type { ProjectForUi } from './project-read-model-type';
 | 
				
			||||||
import { canGrantProjectRole } from './can-grant-project-role';
 | 
					import { canGrantProjectRole } from './can-grant-project-role';
 | 
				
			||||||
 | 
					import { batchExecute } from '../../util/batchExecute';
 | 
				
			||||||
 | 
					import metricsHelper from '../../util/metrics-helper';
 | 
				
			||||||
 | 
					import { FUNCTION_TIME } from '../../metric-events';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Days = number;
 | 
					type Days = number;
 | 
				
			||||||
type Count = number;
 | 
					type Count = number;
 | 
				
			||||||
@ -167,6 +170,8 @@ export default class ProjectService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private onboardingReadModel: IOnboardingReadModel;
 | 
					    private onboardingReadModel: IOnboardingReadModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private timer: Function;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(
 | 
					    constructor(
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            projectStore,
 | 
					            projectStore,
 | 
				
			||||||
@ -226,6 +231,11 @@ export default class ProjectService {
 | 
				
			|||||||
        this.eventBus = config.eventBus;
 | 
					        this.eventBus = config.eventBus;
 | 
				
			||||||
        this.projectReadModel = projectReadModel;
 | 
					        this.projectReadModel = projectReadModel;
 | 
				
			||||||
        this.onboardingReadModel = onboardingReadModel;
 | 
					        this.onboardingReadModel = onboardingReadModel;
 | 
				
			||||||
 | 
					        this.timer = (functionName: string) =>
 | 
				
			||||||
 | 
					            metricsHelper.wrapTimer(config.eventBus, FUNCTION_TIME, {
 | 
				
			||||||
 | 
					                className: 'ProjectService',
 | 
				
			||||||
 | 
					                functionName,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async getProjects(
 | 
					    async getProjects(
 | 
				
			||||||
@ -1282,21 +1292,18 @@ export default class ProjectService {
 | 
				
			|||||||
    async statusJob(): Promise<void> {
 | 
					    async statusJob(): Promise<void> {
 | 
				
			||||||
        const projects = await this.projectStore.getAll();
 | 
					        const projects = await this.projectStore.getAll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const statusUpdates = await Promise.all(
 | 
					        // run one project status update at a time every
 | 
				
			||||||
            projects.map((project) => this.getStatusUpdates(project.id)),
 | 
					        void batchExecute(projects, 1, 30_000, async (project) => {
 | 
				
			||||||
        );
 | 
					            const statusUpdate = await this.getStatusUpdates(project.id);
 | 
				
			||||||
 | 
					            await this.projectStatsStore.updateProjectStats(
 | 
				
			||||||
        await Promise.all(
 | 
					 | 
				
			||||||
            statusUpdates.map((statusUpdate) => {
 | 
					 | 
				
			||||||
                return this.projectStatsStore.updateProjectStats(
 | 
					 | 
				
			||||||
                statusUpdate.projectId,
 | 
					                statusUpdate.projectId,
 | 
				
			||||||
                statusUpdate.updates,
 | 
					                statusUpdate.updates,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            }),
 | 
					        });
 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async getStatusUpdates(projectId: string): Promise<ICalculateStatus> {
 | 
					    async getStatusUpdates(projectId: string): Promise<ICalculateStatus> {
 | 
				
			||||||
 | 
					        const stopTimer = this.timer('getStatusUpdates');
 | 
				
			||||||
        const dateMinusThirtyDays = subDays(new Date(), 30).toISOString();
 | 
					        const dateMinusThirtyDays = subDays(new Date(), 30).toISOString();
 | 
				
			||||||
        const dateMinusSixtyDays = subDays(new Date(), 60).toISOString();
 | 
					        const dateMinusSixtyDays = subDays(new Date(), 60).toISOString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1370,6 +1377,7 @@ export default class ProjectService {
 | 
				
			|||||||
                dateMinusThirtyDays,
 | 
					                dateMinusThirtyDays,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        stopTimer();
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            projectId,
 | 
					            projectId,
 | 
				
			||||||
            updates: {
 | 
					            updates: {
 | 
				
			||||||
 | 
				
			|||||||
@ -30,3 +30,4 @@ export * from './arraysHaveSameItems';
 | 
				
			|||||||
export * from './constantTimeCompare';
 | 
					export * from './constantTimeCompare';
 | 
				
			||||||
export * from '../features/metrics/client-metrics/collapseHourlyMetrics';
 | 
					export * from '../features/metrics/client-metrics/collapseHourlyMetrics';
 | 
				
			||||||
export * from '../features/playground/offline-unleash-client';
 | 
					export * from '../features/playground/offline-unleash-client';
 | 
				
			||||||
 | 
					export * from './batchExecute';
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user