From 57fc64af79f38c911d07bd23b240c38a27b5ec59 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Mon, 27 Jan 2020 19:34:10 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20abort=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5=D1=80=D1=82?= =?UTF-8?q?=D0=B5=D1=80=D0=BE=D0=B2=20=D0=BF=D1=80=D0=B8=20=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=B2=D1=80=D0=B5?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B8=20=D0=BE=D0=B6=D0=B8=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=B4=D0=B2=D0=B8=D0=B6=D0=B5=D0=BA?= =?UTF-8?q?=20=D0=BE=D1=87=D0=B5=D1=80=D0=B5=D0=B4=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/Reader/BookConverter/ConvertBase.js | 8 +++++--- .../core/Reader/BookConverter/ConvertDoc.js | 6 +++--- .../core/Reader/BookConverter/ConvertDocX.js | 8 ++++---- .../core/Reader/BookConverter/ConvertEpub.js | 4 ++-- .../core/Reader/BookConverter/ConvertMobi.js | 4 ++-- .../core/Reader/BookConverter/ConvertPdf.js | 4 ++-- .../core/Reader/BookConverter/ConvertRtf.js | 6 +++--- server/core/Reader/BookConverter/index.js | 9 ++++++--- server/core/Reader/ReaderWorker.js | 2 +- server/core/utils.js | 20 +++++++++++++------ 10 files changed, 42 insertions(+), 29 deletions(-) diff --git a/server/core/Reader/BookConverter/ConvertBase.js b/server/core/Reader/BookConverter/ConvertBase.js index 70a1aa7d..98074a06 100644 --- a/server/core/Reader/BookConverter/ConvertBase.js +++ b/server/core/Reader/BookConverter/ConvertBase.js @@ -14,7 +14,7 @@ class ConvertBase { this.calibrePath = `${config.dataDir}/calibre/ebook-convert`; this.sofficePath = '/usr/bin/soffice'; this.pdfToHtmlPath = '/usr/bin/pdftohtml'; - this.queue = new LimitedQueue(2, 20, 3*60*1000); + this.queue = new LimitedQueue(2, 20, 3*60*1000);//3 минуты ожидание подвижек } async run(data, opts) {// eslint-disable-line no-unused-vars @@ -32,7 +32,7 @@ class ConvertBase { throw new Error('Внешний конвертер pdftohtml не найден'); } - async execConverter(path, args, onData) { + async execConverter(path, args, onData, abort) { let q = null; try { q = await this.queue.get(() => {onData();}); @@ -41,7 +41,7 @@ class ConvertBase { } try { - const result = await utils.spawnProcess(path, {args, onData}); + const result = await utils.spawnProcess(path, {args, onData, abort}); if (result.code != 0) { let error = result.code; if (this.config.branch == 'development') @@ -51,6 +51,8 @@ class ConvertBase { } catch(e) { if (e.status == 'killed') { throw new Error('Слишком долгое ожидание конвертера'); + } else if (e.status == 'abort') { + throw new Error('abort'); } else if (e.status == 'error') { throw new Error(e.error); } else { diff --git a/server/core/Reader/BookConverter/ConvertDoc.js b/server/core/Reader/BookConverter/ConvertDoc.js index ce627eb8..a0c24191 100644 --- a/server/core/Reader/BookConverter/ConvertDoc.js +++ b/server/core/Reader/BookConverter/ConvertDoc.js @@ -16,7 +16,7 @@ class ConvertDoc extends ConvertDocX { return false; await this.checkExternalConverterPresent(); - const {inputFiles, callback} = opts; + const {inputFiles, callback, abort} = opts; const outFile = `${inputFiles.filesDir}/${path.basename(inputFiles.sourceFile)}`; const docFile = `${outFile}.doc`; @@ -24,9 +24,9 @@ class ConvertDoc extends ConvertDocX { const fb2File = `${outFile}.fb2`; await fs.copy(inputFiles.sourceFile, docFile); - await this.execConverter(this.sofficePath, ['--headless', '--convert-to', 'docx', '--outdir', inputFiles.filesDir, docFile]); + await this.execConverter(this.sofficePath, ['--headless', '--convert-to', 'docx', '--outdir', inputFiles.filesDir, docFile], null, abort); - return await super.convert(docxFile, fb2File, callback); + return await super.convert(docxFile, fb2File, callback, abort); } } diff --git a/server/core/Reader/BookConverter/ConvertDocX.js b/server/core/Reader/BookConverter/ConvertDocX.js index d8c85b78..02b112c5 100644 --- a/server/core/Reader/BookConverter/ConvertDocX.js +++ b/server/core/Reader/BookConverter/ConvertDocX.js @@ -20,12 +20,12 @@ class ConvertDocX extends ConvertBase { return false; } - async convert(docxFile, fb2File, callback) { + async convert(docxFile, fb2File, callback, abort) { let perc = 0; await this.execConverter(this.calibrePath, [docxFile, fb2File], () => { perc = (perc < 100 ? perc + 5 : 50); callback(perc); - }); + }, abort); return await fs.readFile(fb2File); } @@ -35,7 +35,7 @@ class ConvertDocX extends ConvertBase { return false; await this.checkExternalConverterPresent(); - const {inputFiles, callback} = opts; + const {inputFiles, callback, abort} = opts; const outFile = `${inputFiles.filesDir}/${path.basename(inputFiles.sourceFile)}`; const docxFile = `${outFile}.docx`; @@ -43,7 +43,7 @@ class ConvertDocX extends ConvertBase { await fs.copy(inputFiles.sourceFile, docxFile); - return await this.convert(docxFile, fb2File, callback); + return await this.convert(docxFile, fb2File, callback, abort); } } diff --git a/server/core/Reader/BookConverter/ConvertEpub.js b/server/core/Reader/BookConverter/ConvertEpub.js index 79b25b8e..f0f9ba71 100644 --- a/server/core/Reader/BookConverter/ConvertEpub.js +++ b/server/core/Reader/BookConverter/ConvertEpub.js @@ -28,7 +28,7 @@ class ConvertEpub extends ConvertBase { return false; await this.checkExternalConverterPresent(); - const {inputFiles, callback} = opts; + const {inputFiles, callback, abort} = opts; const outFile = `${inputFiles.filesDir}/${path.basename(inputFiles.sourceFile)}`; const epubFile = `${outFile}.epub`; @@ -40,7 +40,7 @@ class ConvertEpub extends ConvertBase { await this.execConverter(this.calibrePath, [epubFile, fb2File], () => { perc = (perc < 100 ? perc + 5 : 50); callback(perc); - }); + }, abort); return await fs.readFile(fb2File); } diff --git a/server/core/Reader/BookConverter/ConvertMobi.js b/server/core/Reader/BookConverter/ConvertMobi.js index e8d6172b..ee8535ef 100644 --- a/server/core/Reader/BookConverter/ConvertMobi.js +++ b/server/core/Reader/BookConverter/ConvertMobi.js @@ -16,7 +16,7 @@ class ConvertMobi extends ConvertBase { return false; await this.checkExternalConverterPresent(); - const {inputFiles, callback} = opts; + const {inputFiles, callback, abort} = opts; const outFile = `${inputFiles.filesDir}/${path.basename(inputFiles.sourceFile)}`; const mobiFile = `${outFile}.mobi`; @@ -28,7 +28,7 @@ class ConvertMobi extends ConvertBase { await this.execConverter(this.calibrePath, [mobiFile, fb2File], () => { perc = (perc < 100 ? perc + 5 : 50); callback(perc); - }); + }, abort); return await fs.readFile(fb2File); } diff --git a/server/core/Reader/BookConverter/ConvertPdf.js b/server/core/Reader/BookConverter/ConvertPdf.js index be885369..397a1868 100644 --- a/server/core/Reader/BookConverter/ConvertPdf.js +++ b/server/core/Reader/BookConverter/ConvertPdf.js @@ -18,7 +18,7 @@ class ConvertPdf extends ConvertHtml { return false; await this.checkExternalConverterPresent(); - const {inputFiles, callback} = opts; + const {inputFiles, callback, abort} = opts; const outFile = `${inputFiles.filesDir}/${utils.randomHexString(10)}.xml`; @@ -27,7 +27,7 @@ class ConvertPdf extends ConvertHtml { await this.execConverter(this.pdfToHtmlPath, ['-c', '-s', '-xml', inputFiles.sourceFile, outFile], () => { perc = (perc < 80 ? perc + 10 : 40); callback(perc); - }); + }, abort); callback(80); const data = await fs.readFile(outFile); diff --git a/server/core/Reader/BookConverter/ConvertRtf.js b/server/core/Reader/BookConverter/ConvertRtf.js index 61f489f7..5f167cd6 100644 --- a/server/core/Reader/BookConverter/ConvertRtf.js +++ b/server/core/Reader/BookConverter/ConvertRtf.js @@ -16,7 +16,7 @@ class ConvertRtf extends ConvertDocX { return false; await this.checkExternalConverterPresent(); - const {inputFiles, callback} = opts; + const {inputFiles, callback, abort} = opts; const outFile = `${inputFiles.filesDir}/${path.basename(inputFiles.sourceFile)}`; const rtfFile = `${outFile}.rtf`; @@ -24,9 +24,9 @@ class ConvertRtf extends ConvertDocX { const fb2File = `${outFile}.fb2`; await fs.copy(inputFiles.sourceFile, rtfFile); - await this.execConverter(this.sofficePath, ['--headless', '--convert-to', 'docx', '--outdir', inputFiles.filesDir, rtfFile]); + await this.execConverter(this.sofficePath, ['--headless', '--convert-to', 'docx', '--outdir', inputFiles.filesDir, rtfFile], null, abort); - return await super.convert(docxFile, fb2File, callback); + return await super.convert(docxFile, fb2File, callback, abort); } } diff --git a/server/core/Reader/BookConverter/index.js b/server/core/Reader/BookConverter/index.js index 89b73f5a..d91de21e 100644 --- a/server/core/Reader/BookConverter/index.js +++ b/server/core/Reader/BookConverter/index.js @@ -26,11 +26,14 @@ class BookConverter { } } - async convertToFb2(inputFiles, outputFile, opts, callback) { + async convertToFb2(inputFiles, outputFile, opts, callback, abort) { + if (abort && abort()) + throw new Error('abort'); + const selectedFileType = await this.detector.detectFile(inputFiles.selectedFile); const data = await fs.readFile(inputFiles.selectedFile); - const convertOpts = Object.assign({}, opts, {inputFiles, callback, dataType: selectedFileType}); + const convertOpts = Object.assign({}, opts, {inputFiles, callback, abort, dataType: selectedFileType}); let result = false; for (const convert of this.convertFactory) { result = await convert.run(data, convertOpts); @@ -41,7 +44,7 @@ class BookConverter { } if (!result && inputFiles.nesting) { - result = await this.convertToFb2(inputFiles.nesting, outputFile, opts, callback); + result = await this.convertToFb2(inputFiles.nesting, outputFile, opts, callback, abort); } if (!result) { diff --git a/server/core/Reader/ReaderWorker.js b/server/core/Reader/ReaderWorker.js index ac04138f..078bafca 100644 --- a/server/core/Reader/ReaderWorker.js +++ b/server/core/Reader/ReaderWorker.js @@ -27,7 +27,7 @@ class ReaderWorker { this.config.tempPublicDir = `${config.publicDir}/tmp`; fs.ensureDirSync(this.config.tempPublicDir); - this.queue = new LimitedQueue(5, 100, 3*60*1000); + this.queue = new LimitedQueue(5, 100, 5*60*1000);//5 минут ожидание подвижек this.workerState = new WorkerState(); this.down = new FileDownloader(config.maxUploadFileSize); this.decomp = new FileDecompressor(2*config.maxUploadFileSize); diff --git a/server/core/utils.js b/server/core/utils.js index 9591c7d7..53f7a2b3 100644 --- a/server/core/utils.js +++ b/server/core/utils.js @@ -37,8 +37,8 @@ async function touchFile(filename) { } function spawnProcess(cmd, opts) { - let {args, killAfter, onData} = opts; - killAfter = (killAfter ? killAfter : 120*1000); + let {args, killAfter, onData, abort} = opts; + killAfter = (killAfter ? killAfter : 120);//seconds onData = (onData ? onData : () => {}); args = (args ? args : []); @@ -67,10 +67,18 @@ function spawnProcess(cmd, opts) { reject({status: 'error', error, stdout, stderr}); }); - await sleep(killAfter); - if (!resolved) { - process.kill(proc.pid); - reject({status: 'killed', stdout, stderr}); + while (!resolved) { + await sleep(1000); + killAfter -= 1; + if (killAfter <= 0 || (abort && abort())) { + process.kill(proc.pid); + if (killAfter <= 0) { + reject({status: 'killed', stdout, stderr}); + } else { + reject({status: 'abort', stdout, stderr}); + } + break; + } } })().catch(reject); }); }