【发布时间】:2017-06-11 06:03:10
【问题描述】:
原来的问题
我正在使用 express 创建一个 API,它查询 sqlite DB 并使用 html-pdf 模块将结果输出为 PDF。
问题是某些查询可能需要很长时间才能处理,因此希望将实际查询调用与运行 express 的节点服务器分离,否则如果多个客户端运行繁重的查询,API 可能会变慢.
我解决这个问题的想法是解耦 sqlite 查询的执行,而是在 python 脚本上运行它。然后可以从 API 调用此脚本,从而避免使用节点查询数据库。
当前问题
在快速创建一个运行 sqlite 查询的 python 脚本并使用 child_process.spawn() 从我的 API 调用它之后,我发现 express 似乎在 python 脚本开始执行查询时立即获得退出代码信号。
为了确认这一点,我创建了一个简单的 python 脚本,它只是在打印两条消息之间休眠并且问题被隔离了。
要重现此行为,您可以创建如下 Python 脚本:
print("test 1")
sleep(1)
print("test 2)
然后像这样从 express 中调用它:
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选项(使用无缓冲流)。
这些都没有奏效,所以我猜测 express 中有一些机制可以在生成的进程休眠或完成时关闭请求(而不是仅在完成时)。
我也有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) 时)?
如果我的假设是正确的,即 express 在衍生进程休眠时关闭请求,这是否可以避免?
我找到了suggested the use of ZeroRPC 的一个潜在解决方案,但我不明白这将如何使 express 保持连接打开。
我能想到的唯一其他选项是using something like Kue,这样我的 express API 只需要使用某种作业 ID 进行响应,然后 Kue 将实际生成 python 脚本并等待它的响应,这样我可以通过其他 API 端点查询结果。
我有什么遗漏吗?
编辑:
AllTheTime 关于睡眠问题的评论是正确的。在我添加from time import sleep 之后,它起作用了。但是我的 sqlite 脚本还没有工作。
【问题讨论】:
-
它在睡眠中工作得很好......但是你需要在你的python脚本的顶部正确导入它
from time import sleep如果你运行你的脚本或检查stderr你会看到这个NameError: name 'sleep' is not defined, 退出代码1表示有错误。您的 sqlite python 脚本中可能还有一个您没有看到的错误,因为您没有检查 stderr。您将能够非常快速地判断在close事件中发送的code是否为1。在责备节点之前,请确保您的 python 脚本确实有效! -
啊哈,不错的收获!看来你是对的。但是,即使其中没有错误,它也不适用于 sqlite python 脚本。如果我直接在控制台中运行它,它会按预期工作。但是,一旦我从内部节点调用它,它就会失败。顺便说一句,我绝对不是在责怪节点,更像是责怪自己错过了一些东西 :) 不过感谢您的评论。
标签: python node.js sqlite express