mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: scheduler init jitter (#6071)
This commit is contained in:
		
							parent
							
								
									55b2bb4813
								
							
						
					
					
						commit
						ccc41dca4e
					
				@ -72,7 +72,7 @@ test('Schedules job immediately', async () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const job = jest.fn();
 | 
					    const job = jest.fn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await schedulerService.schedule(job, 10, 'test-id');
 | 
					    await schedulerService.schedule(job, 10, 'test-id', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(job).toBeCalledTimes(1);
 | 
					    expect(job).toBeCalledTimes(1);
 | 
				
			||||||
    schedulerService.stop();
 | 
					    schedulerService.stop();
 | 
				
			||||||
@ -172,7 +172,7 @@ test('Can handle crash of a async job', async () => {
 | 
				
			|||||||
        await Promise.reject('async reason');
 | 
					        await Promise.reject('async reason');
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await schedulerService.schedule(job, 50, 'test-id-10');
 | 
					    await schedulerService.schedule(job, 50, 'test-id-10', 0);
 | 
				
			||||||
    await ms(75);
 | 
					    await ms(75);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    schedulerService.stop();
 | 
					    schedulerService.stop();
 | 
				
			||||||
@ -236,3 +236,29 @@ it('should emit scheduler job time event when scheduled function is run', async
 | 
				
			|||||||
    await schedulerService.schedule(mockJob, 50, 'testJobId');
 | 
					    await schedulerService.schedule(mockJob, 50, 'testJobId');
 | 
				
			||||||
    await eventPromise;
 | 
					    await eventPromise;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('Delays initial job execution by jitter duration', async () => {
 | 
				
			||||||
 | 
					    const { schedulerService } = createSchedulerTestService();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const job = jest.fn();
 | 
				
			||||||
 | 
					    const jitterMs = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await schedulerService.schedule(job, 10000, 'test-id', jitterMs);
 | 
				
			||||||
 | 
					    expect(job).toBeCalledTimes(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await ms(50);
 | 
				
			||||||
 | 
					    expect(job).toBeCalledTimes(1);
 | 
				
			||||||
 | 
					    schedulerService.stop();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('Does not apply jitter if schedule interval is smaller than max jitter', async () => {
 | 
				
			||||||
 | 
					    const { schedulerService } = createSchedulerTestService();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const job = jest.fn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // default jitter 2s-30s
 | 
				
			||||||
 | 
					    await schedulerService.schedule(job, 1000, 'test-id');
 | 
				
			||||||
 | 
					    expect(job).toBeCalledTimes(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    schedulerService.stop();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,19 @@ import { Logger, LogProvider } from '../../logger';
 | 
				
			|||||||
import { IMaintenanceStatus } from '../maintenance/maintenance-service';
 | 
					import { IMaintenanceStatus } from '../maintenance/maintenance-service';
 | 
				
			||||||
import { SCHEDULER_JOB_TIME } from '../../metric-events';
 | 
					import { SCHEDULER_JOB_TIME } from '../../metric-events';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// returns between min and max seconds in ms
 | 
				
			||||||
 | 
					// when schedule interval is smaller than max jitter then no jitter
 | 
				
			||||||
 | 
					function randomJitter(
 | 
				
			||||||
 | 
					    minMs: number,
 | 
				
			||||||
 | 
					    maxMs: number,
 | 
				
			||||||
 | 
					    scheduleIntervalMs: number,
 | 
				
			||||||
 | 
					): number {
 | 
				
			||||||
 | 
					    if (scheduleIntervalMs < maxMs) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return Math.random() * (maxMs - minMs) + minMs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class SchedulerService {
 | 
					export class SchedulerService {
 | 
				
			||||||
    private intervalIds: NodeJS.Timeout[] = [];
 | 
					    private intervalIds: NodeJS.Timeout[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -26,6 +39,7 @@ export class SchedulerService {
 | 
				
			|||||||
        scheduledFunction: () => void,
 | 
					        scheduledFunction: () => void,
 | 
				
			||||||
        timeMs: number,
 | 
					        timeMs: number,
 | 
				
			||||||
        id: string,
 | 
					        id: string,
 | 
				
			||||||
 | 
					        jitter = randomJitter(2 * 1000, 30 * 1000, timeMs),
 | 
				
			||||||
    ): Promise<void> {
 | 
					    ): Promise<void> {
 | 
				
			||||||
        const runScheduledFunctionWithEvent = async () => {
 | 
					        const runScheduledFunctionWithEvent = async () => {
 | 
				
			||||||
            const startTime = process.hrtime();
 | 
					            const startTime = process.hrtime();
 | 
				
			||||||
@ -61,9 +75,16 @@ export class SchedulerService {
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            const maintenanceMode =
 | 
					            const maintenanceMode =
 | 
				
			||||||
                await this.maintenanceStatus.isMaintenanceMode();
 | 
					                await this.maintenanceStatus.isMaintenanceMode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!maintenanceMode) {
 | 
					            if (!maintenanceMode) {
 | 
				
			||||||
 | 
					                if (jitter) {
 | 
				
			||||||
 | 
					                    setTimeout(() => {
 | 
				
			||||||
 | 
					                        runScheduledFunctionWithEvent();
 | 
				
			||||||
 | 
					                    }, jitter);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
                    await runScheduledFunctionWithEvent();
 | 
					                    await runScheduledFunctionWithEvent();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } catch (e) {
 | 
					        } catch (e) {
 | 
				
			||||||
            this.logger.error(`initial scheduled job failed | id: ${id}`, e);
 | 
					            this.logger.error(`initial scheduled job failed | id: ${id}`, e);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user