mStream/src/db/task-queue.js
IrosTheBeggar 7ffc8012d7 whoops
2021-06-09 22:20:33 -04:00

111 lines
3.1 KiB
JavaScript

const child = require('child_process');
const path = require('path');
const winston = require('winston');
const nanoid = require('nanoid');
const jwt = require('jsonwebtoken');
const config = require('../state/config');
const taskQueue = [];
const runningTasks = new Set();
const vpathLimiter = new Set();
let scanIntervalTimer = null; // This gets set after the server boots
function addScanTask(vpath) {
const scanObj = { task: 'scan', vpath: vpath, id: nanoid.nanoid(8) };
if (runningTasks.size < config.program.scanOptions.maxConcurrentTasks) {
runScan(scanObj);
} else {
taskQueue.push(scanObj);
}
}
function removeTask(taskId) {
}
function scanAll() {
Object.keys(config.program.folders).forEach((vpath) => {
addScanTask(vpath);
});
}
function nextTask() {
if (
taskQueue.length > 0
&& runningTasks.size < config.program.scanOptions.maxConcurrentTasks
&& !vpathLimiter.has(taskQueue[taskQueue.length - 1].vpath))
{
runScan(taskQueue.pop());
}
}
function runScan(scanObj) {
const jsonLoad = {
directory: config.program.folders[scanObj.vpath].root,
vpath: scanObj.vpath,
port: config.program.port,
token: jwt.sign({ scan: true }, config.program.secret),
albumArtDirectory: config.program.storage.albumArtDirectory,
skipImg: config.program.scanOptions.skipImg,
pause: config.program.scanOptions.pause,
supportedFiles: config.program.supportedAudioFiles,
scanId: scanObj.id,
isHttps: config.getIsHttps()
};
const forkedScan = child.fork(path.join(__dirname, './scanner.js'), [JSON.stringify(jsonLoad)], { silent: true });
winston.info(`File scan started on ${jsonLoad.directory}`);
runningTasks.add(forkedScan);
vpathLimiter.add(scanObj.vpath);
forkedScan.stdout.on('data', (data) => {
winston.info(`File scan message: ${data}`);
});
forkedScan.stderr.on('data', (data) => {
winston.error(`File scan error: ${data}`);
});
forkedScan.on('close', (code) => {
winston.info(`File scan completed with code ${code}`);
runningTasks.delete(forkedScan);
vpathLimiter.delete(scanObj.vpath);
nextTask();
});
}
exports.scanVPath = (vPath) => {
addScanTask(vPath);
}
exports.scanAll = () => {
scanAll();
}
exports.isScanning = () => {
return runningTasks.size > 0 ? true : false;
}
exports.getAdminStats = () => {
return {
taskQueue,
vpaths: [...vpathLimiter]
};
}
exports.runAfterBoot = () => {
setTimeout(() => {
// This only gets run once after boot. Will not be run on server restart b/c scanIntervalTimer is already set
if (config.program.scanOptions.scanInterval > 0 && scanIntervalTimer === null) {
scanAll();
scanIntervalTimer = setInterval(() => scanAll(), config.program.scanOptions.scanInterval * 60 * 60 * 1000);
}
}, config.program.scanOptions.bootScanDelay * 1000);
}
exports.resetScanInterval = () => {
if (scanIntervalTimer) { clearInterval(scanIntervalTimer); }
if (config.program.scanOptions.scanInterval > 0) {
scanIntervalTimer = setInterval(() => scanAll(), config.program.scanOptions.scanInterval * 60 * 60 * 1000);
}
}