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,8 +75,15 @@ export class SchedulerService { | |||||||
|         try { |         try { | ||||||
|             const maintenanceMode = |             const maintenanceMode = | ||||||
|                 await this.maintenanceStatus.isMaintenanceMode(); |                 await this.maintenanceStatus.isMaintenanceMode(); | ||||||
|  | 
 | ||||||
|             if (!maintenanceMode) { |             if (!maintenanceMode) { | ||||||
|                 await runScheduledFunctionWithEvent(); |                 if (jitter) { | ||||||
|  |                     setTimeout(() => { | ||||||
|  |                         runScheduledFunctionWithEvent(); | ||||||
|  |                     }, jitter); | ||||||
|  |                 } else { | ||||||
|  |                     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