最近,我使用flask-sq与flask-sqlalchemy对模型操作进行了一些异步任务。虽然它在调用模型方法时偶尔会引发ResourceClosedError
错误。我不知道我的rq-worker发生了什么事情导致了这个问题。我无法正确重现该问题。这是片段。
worker.py
if __name__ == '__main__':
with app.app_context():
QUEUE = get_queue()
worker = get_worker()
worker.push_exc_handler(retry_handler)
worker.work()
tasks.py (包含一些异步任务)
@job
def async_restart_task(task_id):
creating_info = {"status": TaskStatus.Creating}
task = TaskModel.update_task(task_id, creating_info)
task = TaskModel.get_task_by_id(task_id)
service = get_service(task.service)
for jobs in iter_group(10, service.gen_jobs(task)):
JobModel.add_jobs(jobs)
异步任务偶尔会引发ResourceClosedError
ResourceClosedError: This result object does not return rows. It has been closed automatically.
我不知道如何通过遵循良好做法来解决问题。我已经搜索了很长一段时间并遇到了同样的问题。参考:Celery and SQLAlchemy - This result object does not return rows. It has been closed automatically
在async-task中使用sqlalchemy是否有任何好的建议或示例?
答案 0 :(得分:0)
我得到了一个很好的总结和建议来自the same question在multi-processes
用例中使用sqlalchemy喜欢使用flask-rq的代码。感谢sqlalchemy的作者@zzzeek给我一个很好的解释。
它告诉我们,当使用sqlalchemy通过共享多进程或工作者之间的连接时,很容易发生这个类问题。我们最好实例化一个新的engine
来完成另一个进程的工作,比如分叉的子进程。
因此,当使用像celery
或RQ
这样的异步队列以及使用sqlalchemy的任何其他队列时。最好从原始Job
或Task
类继承以设置新的engine
或session
来修复此问题。从same issue
最后。您可以按照@zzzeek的一些建议或说明来参考sqlalchemy FAQ