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

feat: scheduler init jitter (#6071)

This commit is contained in:
Mateusz Kwasniewski 2024-01-30 15:49:35 +01:00 committed by GitHub
parent 55b2bb4813
commit ccc41dca4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 3 deletions

View File

@ -72,7 +72,7 @@ test('Schedules job immediately', async () => {
const job = jest.fn();
await schedulerService.schedule(job, 10, 'test-id');
await schedulerService.schedule(job, 10, 'test-id', 0);
expect(job).toBeCalledTimes(1);
schedulerService.stop();
@ -172,7 +172,7 @@ test('Can handle crash of a async job', async () => {
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);
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 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();
});

View File

@ -3,6 +3,19 @@ import { Logger, LogProvider } from '../../logger';
import { IMaintenanceStatus } from '../maintenance/maintenance-service';
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 {
private intervalIds: NodeJS.Timeout[] = [];
@ -26,6 +39,7 @@ export class SchedulerService {
scheduledFunction: () => void,
timeMs: number,
id: string,
jitter = randomJitter(2 * 1000, 30 * 1000, timeMs),
): Promise<void> {
const runScheduledFunctionWithEvent = async () => {
const startTime = process.hrtime();
@ -61,8 +75,15 @@ export class SchedulerService {
try {
const maintenanceMode =
await this.maintenanceStatus.isMaintenanceMode();
if (!maintenanceMode) {
await runScheduledFunctionWithEvent();
if (jitter) {
setTimeout(() => {
runScheduledFunctionWithEvent();
}, jitter);
} else {
await runScheduledFunctionWithEvent();
}
}
} catch (e) {
this.logger.error(`initial scheduled job failed | id: ${id}`, e);