限制更新频率/清除更新缓存

时间:2012-01-26 17:07:11

标签: python caching asynchronous refresh frequency

我有一个用户界面,它接收来自服务的异步通知,提示它重新读取数据库中的信息。异步通知包含可用于检索已修改记录的主键。在负载下,我可能每秒收到10或15个通知,但通常会有重复的ID。像这样:

{u'callback': u'job.modify', u'job-id': 1090, u'timestamp': u'2012-01-26 09:50:04.766'}
{u'callback': u'job.modify', u'job-id': 1091, u'timestamp': u'2012-01-26 09:50:04.767'}
{u'callback': u'job.modify', u'job-id': 1090, u'timestamp': u'2012-01-26 09:50:04.780'}
{u'callback': u'job.modify', u'job-id': 1091, u'timestamp': u'2012-01-26 09:50:04.808'}
{u'callback': u'job.modify', u'job-id': 1090, u'timestamp': u'2012-01-26 09:50:04.812'}
{u'callback': u'job.modify', u'job-id': 1090, u'timestamp': u'2012-01-26 09:50:04.829'}
{u'callback': u'job.modify', u'job-id': 1088, u'timestamp': u'2012-01-26 09:50:04.831'}
{u'callback': u'job.modify', u'job-id': 1088, u'timestamp': u'2012-01-26 09:50:04.836'}
{u'callback': u'job.modify', u'job-id': 1091, u'timestamp': u'2012-01-26 09:50:04.846'}

在这种情况下跳过一些数据库读取似乎是值得的。我正在上课,所以我的想法是配置某种刷新间隔。这就是我到目前为止所做的:

class myClass():
  def __init__(self):
    self.modified = set([])
    self.lastrefresh = datetime.datetime.now()
    self.refreshinterval = datetime.timedelta(milliseconds = 250)

  def onModify(self, data):
    self.modified.add(data['job-id'])
    if datetime.datetime.now() - self.lastrefresh < self.refreshinterval:
      return
    self.doModify()

  def doModify():
    ids = list(self.modified)
    self.lastrefresh = datetime.datetime.now()
    self.modified.clear()

哪个(大多数)有效,但有可能留下一些更新。因为这些更新是异步接收的,所以我不知道它们会显示多少或多少次。任何挂起的刷新都会在下一个通知中处理,但如果下一个通知没有及时到达,那么ID会在修改后的集合中停留超过我想要的250毫秒间隔。任何建议都非常感谢。

1 个答案:

答案 0 :(得分:1)

我想我找到了一种方法来完成这项工作。它需要对类进行以下修改:

class myClass():
  def __init__(self):
    self.modified = set([])
    self.lastrefresh = datetime.datetime.now()
    self.refreshinterval = datetime.timedelta(milliseconds = 250)

  def onModify(self, data):
    self.modified.add(data['job-id'])
    if datetime.datetime.now() - self.lastrefresh < self.refreshinterval:
      return
    self.doModify()

  def doModify():
    if not self.modified:
      return
    ids = list(self.modified)
    self.lastrefresh = datetime.datetime.now()
    self.modified.clear()
    wx.CallAfter(self.purgeModifies)

  def purgeModifies(self):
    wx.CallLater(250, self.doModify)

使用wx.CallAfter然后立即调用wx.CallLater感觉有点兴奋,但onModify正在后台线程中发生,这意味着wx.CallLater会抛出C ++断言错误。 wx.CallAfter将控制权返回给主线程,这允许wx.CallLater工作。这让我得到了另外一次&#34;处理任何待处理的更新。