@pubby/sdk
Version:
Pubby Development Kit
149 lines (146 loc) • 5.54 kB
JavaScript
import { __extends, __assign } from 'tslib';
import { PubbyModule } from '../../module.js';
import { isInterval } from './types.js';
var SchedulerModule = /** @class */ (function (_super) {
__extends(SchedulerModule, _super);
function SchedulerModule(pubby, options) {
var _this = _super.call(this, pubby, __assign({ getTime: function () { return _this.pubby.ws.now; }, time: 1000 }, options)) || this;
_this.pendingCalls = new Map();
_this.tasks = new Map();
// Expoe uma referência deste módulo
pubby.scheduler = _this;
return _this;
}
Object.defineProperty(SchedulerModule.prototype, "now", {
/** Retorna o tempo atual */
get: function () {
return this.options.getTime();
},
enumerable: false,
configurable: true
});
/** Iniciar agendador quando o módulo for inicializado */
SchedulerModule.prototype.init = function () {
this.start();
};
/** Inicia o agendador, caso ele esteja parado */
SchedulerModule.prototype.start = function () {
var _this = this;
if (!this.intervalUpdate) {
this.stop();
this.intervalUpdate = setInterval(function () { return _this.update(); }, this.options.time);
this.update();
}
return this;
};
/** Para o agendador */
SchedulerModule.prototype.stop = function () {
clearInterval(this.intervalUpdate);
this.intervalUpdate = undefined;
this.pendingCalls.forEach(function (id) { return clearTimeout(id); });
this.pendingCalls.clear();
return this;
};
/** Executa uma task */
SchedulerModule.prototype.run = function (task) {
if (!task)
return;
this.pendingCalls.delete(task.id);
if (isInterval(task)) {
task.timestamp = this.now + task.interval;
if (this.intervalUpdate) {
this.requestRun(task);
}
}
else {
this.cancel(task.id);
}
task.run();
};
/** Atrasa a execução de uma task */
SchedulerModule.prototype.callAfterTime = function (task, timeout) {
var _this = this;
if (this.pendingCalls.has(task.id)) {
clearTimeout(this.pendingCalls.get(task.id));
}
var call = function () { return _this.run(task); };
if (timeout <= 0) {
call();
}
else {
this.pendingCalls.set(task.id, setTimeout(call, timeout));
}
return this;
};
/** Atualiza o agendador */
SchedulerModule.prototype.update = function (time) {
var _this = this;
if (time === void 0) { time = this.now; }
this.tasks.forEach(function (task) { return _this.requestRun(task, time); });
if (!this.tasks.size) {
return this.stop();
}
};
/** Define uma nova tarefa */
SchedulerModule.prototype.set = function (task) {
this.cancel(task.id);
this.tasks.set(task.id, task);
if (this.intervalUpdate) {
this.requestRun(task);
}
return this.start();
};
/** Executa uma tarefa se estiver na hora */
SchedulerModule.prototype.requestRun = function (task, time) {
var _a;
if (time === void 0) { time = this.now; }
// Tempo que falta para chamar a task
// Se for positivo, a task está no futuro
// Se for negativo, a task está no passado
var timeLeft = ((_a = task.timestamp) !== null && _a !== void 0 ? _a : 0) - time;
// Se a task está atrasada e o atraso é maior
// que o tempo de atualização do schedule e não é um intervalo,
// cancelar a task
if (timeLeft < -this.options.time && !isInterval(task)) {
return this.cancel(task.id);
}
// Chegou no tempo da task, chamar a task
if (timeLeft <= 0) {
return this.run(task);
}
// Ainda não chegou e o tempo da próxima atualização é maior
// então chame após o tempo que falta
if (timeLeft < this.options.time) {
return this.callAfterTime(task, timeLeft);
}
};
/** Define uma tarefa de repetição */
SchedulerModule.prototype.interval = function (task) {
var _a;
this.set(__assign(__assign({}, task), { timestamp: (_a = task.timestamp) !== null && _a !== void 0 ? _a : this.now + task.interval }));
if (task.immediate) {
task.run();
}
return this;
};
/** Define uma tarefa que será executada após algum tempo apartir do tempo atual */
SchedulerModule.prototype.timeout = function (task) {
this.set(__assign(__assign({}, task), { timestamp: this.now + task.time }));
return this;
};
/** Cancela uma tarefa */
SchedulerModule.prototype.cancel = function (id) {
this.tasks.delete(id);
clearTimeout(this.pendingCalls.get(id));
return this;
};
/** Cancela todas as tarefas */
SchedulerModule.prototype.clear = function () {
this.tasks.clear();
this.pendingCalls.forEach(function (id) { return clearTimeout(id); });
this.pendingCalls.clear();
return this;
};
return SchedulerModule;
}(PubbyModule));
export { SchedulerModule };