Spaces:
Runtime error
Runtime error
File size: 1,781 Bytes
4327358 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
import { Logger } from 'pino';
type FunctionNoArgs = () => Promise<any>;
/**
* Run a job (function) in some interval,
* but make sure we run exactly ONE job at the same time
*/
export class SinglePeriodicJobRunner {
private interval: NodeJS.Timeout;
private isWorking: boolean = false;
private logger: Logger;
constructor(
private name: string,
private intervalMs: number,
logger: Logger,
private warningOverlap: boolean = true,
private warningOverride: boolean = false,
) {
this.logger = logger.child({
job: name,
class: SinglePeriodicJobRunner.name,
});
}
start(fn: FunctionNoArgs): boolean {
if (this.interval) {
const msg = `Job has been started before, do not schedule it again`;
this.log(this.warningOverride, msg);
return false;
}
this.interval = setInterval(() => {
if (this.isWorking) {
const msg = `Job is already running, skipping this run`;
this.log(this.warningOverlap, msg);
return;
}
this.isWorking = true;
this.logger.debug('Running job...');
fn()
.catch((error) => {
this.logger.error(`Job failed: ${error}`);
this.logger.error(error.stack);
})
.finally(() => {
this.isWorking = false;
this.logger.debug(`Job finished`);
});
}, this.intervalMs);
this.logger.info(`Job started with interval ${this.intervalMs} ms`);
return true;
}
stop() {
if (!this.interval) {
return;
}
clearInterval(this.interval);
this.interval = null;
this.logger.info(`Job stopped`);
}
private log(warning: boolean, msg) {
if (warning) {
this.logger.warn(msg);
} else {
this.logger.info(msg);
}
}
}
|