python - 为什么在使用可尾部 MotorCursor 并关闭 Motor 客户端连接时会出现被忽略的异常?

标签 python mongodb tornado pymongo tornado-motor

我编写了以下简化版本的代码:

from sys import exit
from tornado.ioloop import IOLoop
from tornado.gen import coroutine
from pymongo.errors import CollectionInvalid
from motor import MotorClient


client = MotorClient()
db = client.db_test
coll_name = 'coll_test'
coll = db[coll_name]
cursor = None


@coroutine
def stop():
    yield cursor.close()
    client.disconnect()
    IOLoop.current().stop()
    exit()


@coroutine
def create_cursor():
    global cursor

    try:
        yield db.create_collection(coll_name, capped=True, size=1000000)

    except CollectionInvalid:
        print('Database alredy exists!')

    yield coll.save({})
    yield coll.save({})
    cursor = coll.find(tailable=True, await_data=True)
    yield cursor.fetch_next
    cursor.next_object()

if __name__ == "__main__":
    IOLoop.current().spawn_callback(create_cursor)
    IOLoop.current().call_later(10, stop)
    IOLoop.current().start()

当我运行它时,我随机地没有收到以下两个错误或其中之一:

Exception ignored in: <bound method MotorCursor.__del__ of MotorCursor(<pymongo.cursor.Cursor object at 0x7fd3a31e5400>)>
Traceback (most recent call last):
  File "./env/lib/python3.4/site-packages/motor/__init__.py", line 1798, in __del__
TypeError: 'NoneType' object is not callable
Exception ignored in: <bound method MotorCursor.__del__ of MotorCursor(<pymongo.cursor.Cursor object at 0x7f4bea529c50>)>
Traceback (most recent call last):
  File "./env/lib/python3.4/site-packages/motor/__init__.py", line 1803, in __del__
  File "./env/lib/python3.4/site-packages/motor/__init__.py", line 631, in wrapper
  File "./env/lib/python3.4/site-packages/tornado/gen.py", line 204, in wrapper
TypeError: isinstance() arg 2 must be a type or tuple of types

我正在使用 Python 3.4.3、Tornado 4.1、Pymongo 2.8、Motor 0.4.1 和 MongoDB 2.6.3。

仅当创建光标时 tailableawait_data 选项为 True 时,才会出现此问题。

当我不关闭光标时,我也会收到 Pymongo 的错误。但我认为我应该明确关闭它,因为它是一个可尾游标。

我用谷歌搜索过,但没有运气。有什么建议吗?

最佳答案

这是 Motor 中的一个未知错误,我已在 MOTOR-67 处跟踪并修复了它。 。您发现了几个问题。

首先,Motor 游标的析构函数有一个错误,即使在您调用 close 之后,它也会尝试向 MongoDB 服务器发送“killcursors”消息。您关闭了游标,断开了客户端连接,并退出了 Python 解释器。在解释器关闭期间,游标被破坏并尝试向服务器发送“killcursors”,但客户端已断开连接,因此操作失败并记录警告。这是我已修复的错误,并将在 Motor 0.6 中发布。

您从引用游标的函数中调用 exit(),因此游标的析构函数在解释器关闭期间运行。关闭顺序复杂且不可预测;通常,析构函数在 Greenlet 模块被销毁后运行。当游标析构函数在 line 1798 调用 greenlet.getcurrent() 时,getcurrent 函数已设置为 None,因此出现“TypeError:‘NoneType’对象不可调用”。

我建议不要从函数内调用“exit()”。您对 IOLoop.current().stop() 的调用允许 start 函数返回,并且解释器可以正常退出。

关于python - 为什么在使用可尾部 MotorCursor 并关闭 Motor 客户端连接时会出现被忽略的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30315249/

相关文章:

mongodb - meteor :为每个用户使用不同的数据库

python - Tornado 发送和接收字节

python - 有没有办法在内部打印 Tornado 网络服务器上配置的路由处理程序?

python - 如何在所有条形图子图上显示 x 轴标签?

python - pip install -e 。与 setup.py

node.js - angular2-rc1 http.post 无法正常工作

mongodb - 使用另一个字段的值更新 MongoDB 字段

python - 如何释放端口然后第二次运行Tornado应用程序?

python - Python 处理二进制文件有危险吗?

python - 类型错误 : Unrecognized keyword arguments: {'show_accuracy' : True} #yelp challenge dataset