toad-scheduler
Version:
In-memory Node.js and browser job scheduler
91 lines • 3.41 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleIntervalJob = void 0;
const AsyncTask_1 = require("../../common/AsyncTask");
const Job_1 = require("../../common/Job");
const SimpleIntervalSchedule_1 = require("./SimpleIntervalSchedule");
class SimpleIntervalJob extends Job_1.Job {
constructor(schedule, task, options = {}) {
var _a;
super(options.id);
this.preventOverrun = (_a = options.preventOverrun) !== null && _a !== void 0 ? _a : true;
this.unref = options.unref;
this.schedule = schedule;
this.task = task;
}
/**
* Start the job.
*
* Lifecycle invariant: the underlying timer is set up first, and any
* `runImmediately` execution happens last. A `stop()` call issued from
* inside the immediate task (sync) therefore finds an active timer to
* clear, preventing the dangling-timer / double-run bug from #176.
* `LongIntervalJob.start()` follows the same shape.
*/
start() {
var _a, _b;
const time = (0, SimpleIntervalSchedule_1.toMsecs)(this.schedule);
// See https://github.com/kibertoad/toad-scheduler/issues/24
if (time >= 2147483647) {
throw new Error('Due to setInterval limitations, no intervals longer than 24.85 days can be scheduled correctly. Please create LongIntervalJob instead.');
}
// Avoid starting duplicates and leaking previous timers
if (this.timer) {
this.stop();
}
this.timer = setInterval(() => {
if (!this.task.isExecuting || !this.preventOverrun) {
this.task.execute(this.id);
}
}, time);
if (this.unref) {
// Optional call keeps this browser-safe: there setInterval returns a
// number, so `.unref` is undefined and the call short-circuits.
(_b = (_a = this.timer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
}
if (this.schedule.runImmediately) {
this.task.execute(this.id);
}
}
stop() {
if (!this.timer) {
return;
}
clearInterval(this.timer);
this.timer = undefined;
}
applyUnrefDefault(unref) {
var _a, _b;
if (this.unref !== undefined) {
return;
}
this.unref = unref;
if (this.unref && this.timer) {
// Node allows unref() on an already-running timer
(_b = (_a = this.timer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
}
}
getStatus() {
if (this.timer) {
return Job_1.JobStatus.RUNNING;
}
return Job_1.JobStatus.STOPPED;
}
async executeAsync() {
if (!this.task.isExecuting || !this.preventOverrun) {
if ((0, AsyncTask_1.isAsyncTask)(this.task)) {
await this.task.executeAsync(this.id);
}
else {
this.task.execute(this.id);
}
}
}
static async createAndExecute(schedule, task, options = {}) {
const job = new SimpleIntervalJob(Object.assign(Object.assign({}, schedule), { runImmediately: false }), task, options);
await job.executeAsync();
return job;
}
}
exports.SimpleIntervalJob = SimpleIntervalJob;
//# sourceMappingURL=SimpleIntervalJob.js.map