lib/daemon-sync.js
Rama main · réplica de lectura del repositorio original.
/**
* Shared daemon synchronization loop.
*
* Periodic daemon work registers here so every project shares one timer.
*/
function attachDaemonSync(ctx) {
var intervalMs = ctx.intervalMs || 10000;
var scheduleInterval = ctx.setInterval || setInterval;
var cancelInterval = ctx.clearInterval || clearInterval;
var onError = ctx.onError || function (key, err) {
console.error("[daemon] Sync task failed:", key, err);
};
var tasks = {};
var timer = null;
function finishTask(task) {
task.running = false;
}
function runTask(key, task) {
if (task.running) return;
task.running = true;
var result;
try {
result = task.run();
} catch (err) {
finishTask(task);
onError(key, err);
return;
}
if (result && typeof result.then === "function") {
Promise.resolve(result).then(function () {
finishTask(task);
}, function (err) {
finishTask(task);
onError(key, err);
});
return;
}
finishTask(task);
}
function tick() {
var keys = Object.keys(tasks);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var task = tasks[key];
if (task) runTask(key, task);
}
}
function start() {
if (timer || Object.keys(tasks).length === 0) return;
timer = scheduleInterval(tick, intervalMs);
if (timer && typeof timer.unref === "function") timer.unref();
}
function register(key, run) {
var current = tasks[key];
if (current) {
current.run = run;
} else {
tasks[key] = { run: run, running: false };
}
start();
}
function unregister(key) {
delete tasks[key];
if (Object.keys(tasks).length === 0 && timer) {
cancelInterval(timer);
timer = null;
}
}
function stop() {
if (timer) cancelInterval(timer);
timer = null;
tasks = {};
}
function getTaskCount() {
return Object.keys(tasks).length;
}
function isRunning() {
return !!timer;
}
return {
register: register,
unregister: unregister,
tick: tick,
stop: stop,
getTaskCount: getTaskCount,
isRunning: isRunning,
};
}
var daemonSync = attachDaemonSync({});
module.exports = {
attachDaemonSync: attachDaemonSync,
daemonSync: daemonSync,
};