3

我将 redis-py 与 redish 与 gevent 一起使用,并且我有自己的 EventBot 类,它继承自 Greenlet。

__init__这个类的方法中,我正在初始化与 redis 的连接

self._redis = Client(serializer=serialization.JSON(), **self.REDIS_CONFIG)

有时当我尝试运行脚本时,它会抛出,SystemError: NULL result without error in PyObject_Call但有时它会正常启动。我也尝试将 redis 初始化移动到_run()方法中,但没有帮助。

这是我正在使用的简化类:

from gevent import monkey, Greenlet
monkey.patch_all()

from sleekxmpp import ClientXMPP
from redish import serialization
from redish.client import Client


class EventBot(ClientXMPP, Greenlet):
    REDIS_CONFIG = {
        'host': 'localhost',
        'port': 6379,
        'db': ""
    }

    def __init__(self, jid, password, redis_config=None):
        ClientXMPP.__init__(self, jid, password)
        Greenlet.__init__(self)

        # Redis init
        if redis_config is not None:
            self.REDIS_CONFIG.update(redis_config)
        self._redis = Client(serializer=serialization.JSON(), **self.REDIS_CONFIG)

        QUESTIONS_KEY = __name__ + '_questions'
        try:
            self._questions = self._redis[QUESTIONS_KEY]
        except KeyError:
            self._questions = self._redis[QUESTIONS_KEY] = {}

    ## Class simplified for better readability ##

    def _run(self):
        self.connect()
        self.process(block=False)

这是完整的回溯:

Traceback (most recent call last):
  File "start.py", line 15, in <module>
    bot = EventBot('marie@xxx.com', 'XXXpasswordXXX')
  File "/tmp/sandbox/gmarie/gmarie/marie/eventbot.py", line 41, in __init__
    self._questions = self._redis[QUESTIONS_KEY]
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/redish/client.py", line 196, in __getitem__
    value = self.api.get(name)
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/redis/client.py", line 551, in get
    return self.execute_command('GET', name)
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/redis/client.py", line 360, in execute_command
    connection.send_command(*args)
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/redis/connection.py", line 301, in send_command
    self.send_packed_command(self.pack_command(*args))
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/redis/connection.py", line 283, in send_packed_command
    self.connect()
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/redis/connection.py", line 228, in connect
    sock = self._connect()
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/redis/connection.py", line 240, in _connect
    sock.connect((self.host, self.port))
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/gevent/socket.py", line 376, in connect
    wait_readwrite(sock.fileno(), event=self._rw_event)
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/gevent/socket.py", line 215, in wait_readwrite
    switch_result = get_hub().switch()
  File "/tmp/sandbox/gmarie/venv/lib/python2.7/site-packages/gevent/hub.py", line 164, in switch
    return greenlet.switch(self)
SystemError: NULL result without error in PyObject_Call
Exception KeyError: KeyError(21246672,) in <module 'threading' from '/usr/lib64/python2.7/threading.py'> ignored

任何帮助将不胜感激。


编辑:

gevent使用和greenlet系统包(python2-gevent以及在 Arch Linux 中)时,问题似乎已得到解决python2-greenlet,但根据他们的 PKGBUILD,没有在那里进行额外的修补。(geventgreenlet)有人可以解释使用 pip 安装有什么问题吗?

4

2 回答 2

6

greenlet==0.4.0使用的时候好像有问题GCC 4.8

如果您没有较旧的 gcc 或其他可用的编译器,您可以通过使用CFLAGS="-O0" pip install greenlet==0.4.0或编辑 greenletsetup.py和调整来覆盖问题os.environ["CFLAGS"]

其他解决方案可能是下载并使用二进制文件greenlet.so

于 2013-04-12T14:41:50.280 回答
0

根据关于此主题的 GitHub 问题,您还可以使用CFLAGS="-O2 -fno-tree-dominator-opts"获得常规编译器优化但没有段错误。

于 2016-11-01T15:53:28.633 回答