我正在用Tornado开发推送系统。由于我要进行长时间的轮询,我需要保留Future对象的列表,以便稍后为它们设置结果。然后我想在Redis中保留Future列表,所以我用Pickle模块"转储"每个Future并将其设置为Redis,但在我从Redis获得它并"加载"它之后,我发现它不是原来的Future对象,当我对这个Future对象调用set_result函数时,它并没有像我预期的那样工作。
有人能帮我吗?
这是我代码的一部分:
@singleton
class MessageProxy:
def register_subscriber(self, subscriber):
r.set("subscriber", pickle.dumps(subscriber))
def send_message(self, message):
subscriber = pickle.loads(r.get("subscriber"))
subscriber.set_result(message.content)
Future
对象不能进行有效的pickle。一个未完成的Future
只是一个带有回调列表的占位符,不能对回调进行pickle。(此外,回调列表可以随时更改;您可以毫无例外地调用pickle.dumps()
,这意味着您做得太早;应用程序还没有机会附加回调)。
您不需要将Futures
存储在redis中,而是必须在内存中保留一个映射并将标识符存储在redi中。如果您有多个服务器进程,那么当然会有多个这样的映射。您必须通过向每个服务器广播每条消息(不知道谁在听什么)或在redis中包含某种寻址信息来确保消息到达需要的位置。