【问题标题】:redis-py not closing threads on exitredis-py 在退出时不关闭线程
【发布时间】:2020-02-18 15:33:04
【问题描述】:

我正在使用 redis-py 2.10.6 和 redis 4.0.11。

我的应用程序将 redis 用于 db 和 pubsub。当我关闭时,我经常会挂起或崩溃。后者通常抱怨在处理 pubsub 回调时发生的文件描述符错误或文件上的 I/O 错误(我不使用任何错误),所以我猜测根本问题是相同的:不知何故我没有t 正确断开连接,我的 redis.Redis 对象使用的池是活动的。

前一种错误的输出示例(在_read_from_socket期间):

redis.exceptions.ConnectionError: 从套接字读取时出错: (9, 'Bad file descriptor')

其他时候堆栈跟踪清楚地显示 redis/connection.py -> redis/client.py -> threading.py,这证明 redis 没有杀死它使用的线程。

当我为我运行的应用加注星标时:

self.redis = redis.Redis(host=XXXX, port=XXXX)
self.pubsub = self.redis.pubsub()
subscriptions = {'chan1': self.cb1, 'chan2': self.cb2}  # cb1 and cb2 are functions
self.pubsub.subscribe(**subscriptions)
self.pubsub_thread = self.pubsub.run_in_thread(sleep_time=1)

当我想退出应用程序时,我在 ma​​in 中执行的最后一条指令是使用类调用我的 redis 中的函数,其实现是:

self.pubsub.close()
self.pubsub_thread.stop()
self.redis.connection_pool.disconnect()

我的理解是,理论上我什至不需要执行任何这些“关闭”调用,但是,无论有没有它们,我仍然不能保证完全关闭。

我的问题是,我应该如何保证完全关机?

【问题讨论】:

  • 遇到同样的问题。重启应用时重新连接服务器似乎也有问题,我必须连同应用程序一起重启服务器,非常不方便!

标签: python-3.x redis py-redis


【解决方案1】:

我遇到了同样的问题,这主要是由于 redis 库对关闭处理不当造成的。在清理期间,线程继续处理新消息,并且不考虑套接字不再可用的情况。在对代码进行了一番搜索之后,我无法找到一种方法来阻止额外的处理而无需等待。

由于这是在关闭阶段运行的,并且它是对第 3 方库的补救措施,我并不太担心 sleep,但理想情况下应该更新库以防止在关闭时采取进一步行动。

self.pubsub_thread.stop()
time.sleep(0.5)
self.pubsub.reset()

这可能值得在 redis-py 库上发布问题日志或 PR。

【讨论】:

    【解决方案2】:

    PubSubWorkerThread 类检查循环内的self._running.is_set()

    要进行“干净关闭”,您应该调用 self.pubsub_thread._running.clean() 将线程事件设置为 false 并且它将停止。

    在这里检查它是如何工作的: https://redis.readthedocs.io/en/latest/_modules/redis/client.html?highlight=PubSubWorkerThread#

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      • 2014-03-17
      相关资源
      最近更新 更多