为什么在使用 tailable MotorCursor 并关闭 Motor 客户端连接时会出现被忽略的异常?
Why do I get ignored exceptions when using a tailable MotorCursor and closing the Motor client connection?
我编写了以下代码的简化版本:
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()
当我 运行 它时,我随机得到 none 或以下两个错误之一:
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。
只有在创建游标时 tailable
和 await_data
选项为 True
时才会出现此问题。
当我不关闭光标时,我也会收到 Pymongo 的错误。但我认为我应该明确关闭它,因为它是一个可尾游标。
我用谷歌搜索了它,但没有成功。有什么建议吗?
这是 Motor 中的一个未知错误,我已在 MOTOR-67 跟踪并修复了它。您发现了几个问题。
首先,Motor 游标的析构函数有一个错误,它会尝试向 MongoDB 服务器发送 "killcursors" 消息,即使在您调用关闭之后也是如此。您关闭了游标,断开了客户端,并退出了 Python 解释器。在解释器关闭期间,游标被销毁并尝试将 "killcursors" 发送到服务器,但客户端已断开连接,因此操作失败并记录警告。这是我已修复并将在 Motor 0.6 中发布的错误。
您从引用游标的函数中调用 exit(),因此游标的析构函数在解释器关闭期间运行。关机顺序复杂且不可预测;通常,析构函数在 greenlet
模块被销毁后运行。当游标析构函数在 line 1798 处调用 greenlet.getcurrent()
时,getcurrent
函数已经设置为 None
,因此 "TypeError: 'NoneType' object is not callable".
我建议不要在函数内调用 "exit()"。您对 IOLoop.current().stop()
的调用允许 start
函数 return,并且解释器可以正常退出。
我编写了以下代码的简化版本:
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()
当我 运行 它时,我随机得到 none 或以下两个错误之一:
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。
只有在创建游标时 tailable
和 await_data
选项为 True
时才会出现此问题。
当我不关闭光标时,我也会收到 Pymongo 的错误。但我认为我应该明确关闭它,因为它是一个可尾游标。
我用谷歌搜索了它,但没有成功。有什么建议吗?
这是 Motor 中的一个未知错误,我已在 MOTOR-67 跟踪并修复了它。您发现了几个问题。
首先,Motor 游标的析构函数有一个错误,它会尝试向 MongoDB 服务器发送 "killcursors" 消息,即使在您调用关闭之后也是如此。您关闭了游标,断开了客户端,并退出了 Python 解释器。在解释器关闭期间,游标被销毁并尝试将 "killcursors" 发送到服务器,但客户端已断开连接,因此操作失败并记录警告。这是我已修复并将在 Motor 0.6 中发布的错误。
您从引用游标的函数中调用 exit(),因此游标的析构函数在解释器关闭期间运行。关机顺序复杂且不可预测;通常,析构函数在 greenlet
模块被销毁后运行。当游标析构函数在 line 1798 处调用 greenlet.getcurrent()
时,getcurrent
函数已经设置为 None
,因此 "TypeError: 'NoneType' object is not callable".
我建议不要在函数内调用 "exit()"。您对 IOLoop.current().stop()
的调用允许 start
函数 return,并且解释器可以正常退出。