waha / src /utils /SinglePeriodicJobRunner.ts
NitinBot002's picture
Upload 384 files
4327358 verified
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);
}
}
}