diff --git a/server/core/Reader/BookConverter/ConvertBase.js b/server/core/Reader/BookConverter/ConvertBase.js index 6ba20853..5503f829 100644 --- a/server/core/Reader/BookConverter/ConvertBase.js +++ b/server/core/Reader/BookConverter/ConvertBase.js @@ -6,7 +6,7 @@ const LimitedQueue = require('../../LimitedQueue'); const textUtils = require('./textUtils'); const utils = require('../../utils'); -const queue = new LimitedQueue(2, 20, 3*60*1000);//3 минуты ожидание подвижек +const queue = new LimitedQueue(3, 20, 3*60*1000);//3 минуты ожидание подвижек class ConvertBase { constructor(config) { @@ -44,12 +44,17 @@ class ConvertBase { try { const result = await utils.spawnProcess(path, { - killAfter: 600, + killAfter: 3600,//1 час args, onData: (data) => { q.resetTimeout(); onData(data); }, + //будем периодически проверять работу конвертера и если очереди нет, то разрешаем работу пинком onData + onUsage: (stats) => { + if (queue.freed > 1 && stats.cpu >= 10) + onData('.'); + }, abort }); if (result.code != 0) { diff --git a/server/core/Reader/ReaderWorker.js b/server/core/Reader/ReaderWorker.js index 223f1307..b44061dc 100644 --- a/server/core/Reader/ReaderWorker.js +++ b/server/core/Reader/ReaderWorker.js @@ -130,6 +130,7 @@ class ReaderWorker { convertFilename = `${this.config.tempDownloadDir}/${tempFilename2}`; await this.bookConverter.convertToFb2(decompFiles, convertFilename, opts, progress => { wState.set({progress}); + q.resetTimeout(); }, q.abort); //сжимаем файл в tmp, если там уже нет с тем же именем-sha256 diff --git a/server/core/utils.js b/server/core/utils.js index df27a487..587b72bf 100644 --- a/server/core/utils.js +++ b/server/core/utils.js @@ -3,6 +3,7 @@ const fs = require('fs-extra'); const path = require('path'); const crypto = require('crypto'); const baseX = require('base-x'); +const pidusage = require('pidusage'); const BASE36 = '0123456789abcdefghijklmnopqrstuvwxyz'; const bs36 = baseX(BASE36); @@ -46,10 +47,11 @@ async function touchFile(filename) { } function spawnProcess(cmd, opts) { - let {args, killAfter, onData, abort} = opts; + let {args, killAfter, onData, onUsage, onUsageInterval, abort} = opts; killAfter = (killAfter ? killAfter : 120);//seconds onData = (onData ? onData : () => {}); args = (args ? args : []); + onUsageInterval = (onUsageInterval ? onUsageInterval : 30);//seconds return new Promise((resolve, reject) => { (async() => { let resolved = false; @@ -76,9 +78,19 @@ function spawnProcess(cmd, opts) { reject({status: 'error', error, stdout, stderr}); }); + //ждем процесс, контролируем его работу раз в секунду + let onUsageCounter = onUsageInterval; while (!resolved) { await sleep(1000); - killAfter -= 1; + + onUsageCounter--; + if (onUsage && onUsageCounter <= 0) { + const stats = await pidusage(proc.pid); + onUsage(stats); + onUsageCounter = onUsageInterval; + } + + killAfter--; if (killAfter <= 0 || (abort && abort())) { process.kill(proc.pid); if (killAfter <= 0) {