原始问题
我使用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脚本还没有工作。
答案 0 :(得分:0)
事实证明AllTheTime确实是正确的。
问题是在我的python脚本中我加载了一个config.json文件,该文件在从控制台调用时被正确加载,因为该路径是相对于脚本的。
但是,当从节点调用它时,相对路径不再正确。
修好路径后,它完全符合预期。