Javascript 线程模块给出通道关闭错误

Javascript 线程模块给出通道关闭错误,javascript,node.js,js-xlsx,Javascript,Node.js,Js Xlsx,我正在使用npmxlsx(lib/parserScripts/readExcel.js) 和线程模块读取一个大的excel文件 这是第一次,但如果我同时上传另一个大文件,我会得到一个错误 Error: channel closed at ChildProcess.target.send (internal/child_process.js:554:16) at Worker.send (/app/node_modules/threads/lib/worker.node/worke

我正在使用npmxlsx(lib/parserScripts/readExcel.js) 和线程模块读取一个大的excel文件


这是第一次,但如果我同时上传另一个大文件,我会得到一个错误

Error: channel closed
    at ChildProcess.target.send (internal/child_process.js:554:16)
    at Worker.send (/app/node_modules/threads/lib/worker.node/worker.js:108:16)...
这可能是由于以前的线程仍在处理/尚未终止,因此当为另一个请求创建新池时,以前的线程仍在忙于处理

如何解决这个问题?我必须手动终止下面代码段中的线程吗?如果是的话,那怎么办

index.js

    parseFile: ['fileHeaders', (results, cb) => {
        const excelParserScript = __dirname + '/../lib/parserScripts/readExcel';
        const worksheetIndex = 3;
        const params = {
            file.path,
            worksheetIndex
        }

        // using worker process
        // result will be of the type {error: false, message: '', data: {}}
        lib.miniWorker.bufferedJob(excelParserScript, params, (err, result) => {
const Threads = require('threads');
const Pool = Threads.Pool; 
const workerPool = new Pool();

module.exports = class JobManager {
    static bufferedJob(pathToScript, params, callback){
        workerPool
        .run(pathToScript)
        .send(params)
        .on('done', (result, input) => {
            console.log(`Worker Job done: ${pathToScript} `);
            callback(null, result);
        })
        .on('error', (job, error) => {
            console.log(`Error in executing Worker Job: ${pathToScript}`);
            callback(job || error);
        })
    }
}
lib/miniworker.js

    parseFile: ['fileHeaders', (results, cb) => {
        const excelParserScript = __dirname + '/../lib/parserScripts/readExcel';
        const worksheetIndex = 3;
        const params = {
            file.path,
            worksheetIndex
        }

        // using worker process
        // result will be of the type {error: false, message: '', data: {}}
        lib.miniWorker.bufferedJob(excelParserScript, params, (err, result) => {
const Threads = require('threads');
const Pool = Threads.Pool; 
const workerPool = new Pool();

module.exports = class JobManager {
    static bufferedJob(pathToScript, params, callback){
        workerPool
        .run(pathToScript)
        .send(params)
        .on('done', (result, input) => {
            console.log(`Worker Job done: ${pathToScript} `);
            callback(null, result);
        })
        .on('error', (job, error) => {
            console.log(`Error in executing Worker Job: ${pathToScript}`);
            callback(job || error);
        })
    }
}
lib/parserScripts/readExcel.js

module.exports = function(input, done) {
    const XLSX = require('xlsx');

    let workbook;
    const path = input.path;

    const worksheetIndex = input.worksheetIndex;
    const expectedHeaders = input.expectedHeaders || [];
    const options = {};
    if (expectedHeaders.length > 0) {
        options.header = expectedHeaders;
    }
    const response = {
        error: false,
        message: '',
        data: {}
    }

    try {

        workbook = XLSX.readFile(path, {});
        const sheet = workbook['Sheets'][workbook.SheetNames[worksheetIndex]];
        const headers = getHeaders(sheet);
        const fileData = XLSX.utils.sheet_to_json(workbook['Sheets'][workbook.SheetNames[worksheetIndex]], options);
        response.data = fileData;
        response.headers = headers;
        return done(response)

    } catch (err) {

        response.error = true;
        response.messsage = 'Error in reading the file';
        return done(response);

    }


    function getHeaders(sheet) {
        var header = 0, offset = 1;
        var hdr = [];
        var o = {};
        if (sheet == null || sheet["!ref"] == null) return [];
        var range = o.range !== undefined ? o.range : sheet["!ref"];
        var r;
        if (o.header === 1) header = 1;
        else if (o.header === "A") header = 2;
        else if (Array.isArray(o.header)) header = 3;
        switch (typeof range) {
            case 'string':
                r = safe_decode_range(range);
                break;
            case 'number':
                r = safe_decode_range(sheet["!ref"]);
                r.s.r = range;
                break;
            default:
                r = range;
        }
        if (header > 0) offset = 0;
        var rr = XLSX.utils.encode_row(r.s.r);
        var cols = new Array(r.e.c - r.s.c + 1);
        for (var C = r.s.c; C <= r.e.c; ++C) {
            cols[C] = XLSX.utils.encode_col(C);
            var val = sheet[cols[C] + rr];
            switch (header) {
                case 1:
                    hdr.push(C);
                    break;
                case 2:
                    hdr.push(cols[C]);
                    break;
                case 3:
                    hdr.push(o.header[C - r.s.c]);
                    break;
                default:
                    if (val === undefined) continue;
                    hdr.push(XLSX.utils.format_cell(val));
            }
        }
        return hdr;
    }


    function safe_decode_range(range) {
        var o = {s: {c: 0, r: 0}, e: {c: 0, r: 0}};
        var idx = 0, i = 0, cc = 0;
        var len = range.length;
        for (idx = 0; i < len; ++i) {
            if ((cc = range.charCodeAt(i) - 64) < 1 || cc > 26) break;
            idx = 26 * idx + cc;
        }
        o.s.c = --idx;

        for (idx = 0; i < len; ++i) {
            if ((cc = range.charCodeAt(i) - 48) < 0 || cc > 9) break;
            idx = 10 * idx + cc;
        }
        o.s.r = --idx;

        if (i === len || range.charCodeAt(++i) === 58) {
            o.e.c = o.s.c;
            o.e.r = o.s.r;
            return o;
        }

        for (idx = 0; i != len; ++i) {
            if ((cc = range.charCodeAt(i) - 64) < 1 || cc > 26) break;
            idx = 26 * idx + cc;
        }
        o.e.c = --idx;

        for (idx = 0; i != len; ++i) {
            if ((cc = range.charCodeAt(i) - 48) < 0 || cc > 9) break;
            idx = 10 * idx + cc;
        }
        o.e.r = --idx;
        return o;
    }

}
module.exports=函数(输入,完成){
常量XLSX=要求('XLSX');
让练习册;
const path=input.path;
const worksheetIndex=input.worksheetIndex;
const expectedHeaders=input.expectedHeaders | |[];
常量选项={};
如果(expectedHeaders.length>0){
options.header=expectedHeaders;
}
常数响应={
错误:false,
消息:“”,
数据:{}
}
试一试{
工作簿=XLSX.readFile(路径{});
const sheet=工作簿['Sheets'][workbook.SheetNames[worksheetIndex]];
const headers=getHeaders(表);
const fileData=XLSX.utils.sheet_to_json(工作簿['Sheets'][workbook.SheetNames[worksheetIndex]],选项);
response.data=文件数据;
response.headers=标题;
返回完成(响应)
}捕捉(错误){
response.error=true;
response.message='读取文件时出错';
返回完成(响应);
}
函数getHeaders(工作表){
变量头=0,偏移量=1;
var hdr=[];
var o={};
if(sheet==null | | sheet[“!ref”]==null)返回[];
变量范围=o.range!==未定义?o.range:工作表[“!ref”];
var-r;
如果(o.header==1)header=1;
否则,如果(o.header==“A”)header=2;
如果(Array.isArray(o.header))header=3,则为else;
开关(范围类型){
大小写“string”:
r=安全解码范围(范围);
打破
案件编号:
r=安全解码范围(表[“!ref]”);
r、 s.r=范围;
打破
违约:
r=范围;
}
如果(标题>0)偏移量=0;
var rr=XLSX.utils.encode_行(r.s.r);
var cols=新数组(r.e.c-r.s.c+1);
对于(var C=r.s.C;C 26)断裂;
idx=26*idx+cc;
}
o、 s.c=--idx;
对于(idx=0;i9)中断;
idx=10*idx+cc;
}
o、 s.r=--idx;
if(i==len | | range.charCodeAt(++i)==58){
o、 e.c=o.s.c;
o、 e.r=o.s.r;
返回o;
}
对于(idx=0;i!=len;++i){
如果((cc=range.charCodeAt(i)-64)<1 | | cc>26)中断;
idx=26*idx+cc;
}
o、 e.c=--idx;
对于(idx=0;i!=len;++i){
如果((cc=range.charCodeAt(i)-48)<0 | | cc>9)中断;
idx=10*idx+cc;
}
o、 e.r=--idx;
返回o;
}
}

这是第一次正常工作,但是如果我同时上传另一个大文件,那么我会出错

您应该上传不同的文件名,如final01.xlsx,然后将其重命名为final.xlsx 原因是当您上传文件时,readfile无法完成,因为写入文件会锁定文件并更改内容。
如果上载文件意味着您正在同时读取node.js代码中的另一个大文件,请忽略我的评论。

问题是因为旧版本的线程模块。更新到新版本并使用非基于事件的更新API可以解决此问题。

但是,如果您想要更正基于事件的代码(来自旧版本),这就是您需要做的(在事件完成后杀死线程)


我找不到任何关于你这样做的参考资料。您使用的是什么库?请检查lib/parserScripts/readExcel.js我使用xlsx读取文件@ternalhouri找不到任何内容。我建议您提供文档的链接。这似乎不是一种广为人知的解析excel文件的方法。用于读取excel文件并在工作线程上处理它的npm包。@EternalHourAnd?