与this question相关我有以下代码订阅redis pubsub队列并使用__init__中提供的处理程序将消息提供给处理它们的类:
from threading import Thread
import msgpack
class Subscriber(Thread):
def __init__(self, redis_connection, channel_name, handler):
super(Subscriber, self).__init__(name="Receiver")
self.connection = redis_connection
self.pubsub = self.connection.pubsub()
self.channel_name = channel_name
self.handler = handler
self.should_die = False
def start(self):
self.pubsub.subscribe(self.channel_name)
super(Subscriber, self).start()
def run(self):
for msg in self.pubsub.listen():
if self.should_die:
return
try:
data = msg["data"]
unpacked = msgpack.unpackb(data)
except TypeError:
# stop non-msgpacked, invalid, messages breaking stuff
# other validation happens in handler
continue
self.handler(unpacked)
def die(self):
self.should_die = True
在上面的链接问题中,请注意,如果断开连接,pubsub.listen()
永远不会返回。因此,我的die()
函数虽然可以调用,但实际上永远不会导致线程终止,因为它挂在线程listen()
内run()
的调用上。
关于链接问题的已接受答案提到了黑客redis-py的连接池。我真的不想这样做,并且有一个redis-py的分叉版本(至少直到修复程序被希望接受为master),但我还是看了redis-py代码并且不要马上看看这个改变的地方。
有没有人知道如何干净地解决挂起的redis-py listen()
电话?
直接使用Thread._Thread__stop
会产生哪些问题?