当生成的Python脚本休眠时,Express会关闭请求

时间:2017-01-25 21:35:15

标签: python node.js sqlite express

原始问题

我使用express创建一个API,用于查询sqlite DB并使用html-pdf模块将结果输出为PDF。

问题是某些查询可能需要很长时间才能处理,因此希望将实际查询调用与运行express的节点服务器分离,否则如果多个客户端运行大量查询,API可能会变慢

我解决这个问题的想法是解耦sqlite查询的执行,而不是在python脚本上运行它。然后可以从API调用此脚本,从而避免使用节点查询数据库。

当前问题

在快速创建运行sqlite查询的python脚本并使用child_process.spawn()从我的API调用它之后,我发现当python脚本开始执行时,express似乎会获得退出代码信号查询。

为了确认这一点,我创建了一个简单的python脚本,它只是在打印两条消息之间睡觉,问题被隔离了。

要重现此行为,您可以创建如下的python脚本:

print("test 1")
sleep(1)
print("test 2)

然后从快递中调用它:

router.get('/async', function(req, res, next) {
    var python = child_process.spawn([
        'python3'
    );
    var output = "";
    python.stdout.on('data', function(data){ 
        output += data
        console.log(output)
    });

    python.on('close', function(code){ 
        if (code !== 0) {  
          return res.status(200).send(code) 
        }
        return res.status(200).send(output)
    });
});

如果您随后运行快速服务器并执行GET /async,您将获得一个" 1"作为退出代码。

但是,如果您对sleep(1)行发表评论,则服务器会成功返回

test 1
test 2

作为回应。

您甚至可以使用sleep(0)触发此操作。

我在睡眠前尝试了flushing the stdout,我也tried piping the result而不是.on('close'),我也在调用python时尝试使用-u选项(使用无缓冲流)。

这一切都没有奏效,所以我猜测有一些机制被刻入快递,一旦产生的进程休眠或完成(而不是仅在完成时),就会关闭请求。

我也是found this answer related to using child_process.fork(),但我不确定这是否会有不同的行为this one is very similar to my issue but has no answer

主要问题

所以我的问题是,为什么python脚本在执行sleep()时会发送一个退出信号(或者在运行cursor.execute(query)时我的查询脚本的情况下)?

如果我的假设是正确的,表示在生成的进程休眠时关闭请求,这是否可以避免?

我发现suggested the use of ZeroRPC的一个可能的解决方案,但我不知道如何使快递保持连接畅通。

我能想到的唯一另一个选择是using something like Kue,这样我的快速API只需要用某种作业ID进行响应,然后Kue会生成python脚本并等待它的响应,所以我可以通过其他一些API端点查询结果。

我有什么遗失的吗?

修改

AllTheTime的评论对于睡眠问题是正确的。我添加from time import sleep之后就可以了。但是我的sqlite脚本还没有工作。

1 个答案:

答案 0 :(得分:0)

事实证明AllTheTime确实是正确的。

问题是在我的python脚本中我加载了一个config.json文件,该文件在从控制台调用时被正确加载,因为该路径是相对于脚本的。

但是,当从节点调用它时,相对路径不再正确。

修好路径后,它完全符合预期。