龙卷风处理程序检测另一端关闭的任何方法?

时间:2016-10-14 17:56:25

标签: python python-requests tornado coroutine

我有一个龙卷风协程法案,部分看起来像是:

class QueryHandler(tornado.web.RequestHandler):
    queryQueues = defaultdict(tornado.queues.Queue)

    @tornado.gen.coroutine
    def get(self, network):
        qq = self.queryQueues[network]
        query = yield qq.get()
        # do some work with with the dequeued query
        self.write(response)

在客户端,我使用python-requests对其进行长时间轮询:

fetched = session.get(QueryURL)

我可以进行查询,服务器阻塞等待队列,直到咳出一些东西来处理并最终响应。

这非常灵活,直到...长队列会在处理程序阻塞队列时关闭并重新启动。当我在客户端停止查询时,处理程序保持愉快阻止。更糟糕的是,如果我在客户端重新启动查询,我现在在队列上有第二个处理程序实例阻塞。因此,当队列DOES显示数据时,过时处理程序会处理它并回复bitbucket,现在无限期地阻止重新启动的查询。

我可以用一种模式来避免这种情况吗?我希望当客户端关闭时,处理程序会收到某种异常,表明事情已经发生了变化。 queue.get()可以有一个超时,但我真正想要的不是超时,而是一种“除非我关闭”异常。

1 个答案:

答案 0 :(得分:1)

您想要一个“保证交付的队列”,这是分布式系统中的一个难题。毕竟,即使“self.write”成功,你也无法确定对方是否真的收到了这条消息。

基本方法如下:

  • 队列中的每个条目的id都大于以前的所有ID
  • 当客户端连接它时要求订阅队列
  • 当客户端断开连接时,它会重新连接并要求所有条目的ID大于它看到的最后一个ID
  • 当您的QueryHandler收到带有非get ID的None时,它首先为所有ID大于id的条目提供服务,然后开始等待队列
  • 当您的QueryHandler从self.write引发异常时,忽略它:客户端负责检索丢失的条目
  • 将所有过去的条目保留在列表中
  • 在一段时间(小时?)之后使最旧的列表条目到期。