【问题标题】:Infinite Sequence of requests in Finagle with FutureFinagle 和 Future 中的无限请求序列
【发布时间】:2016-06-23 04:09:31
【问题描述】:

我有一个 HTTP API 端点,我需要不断检查新值。幸运的是,它支持长轮询。所以我的想法是我需要实现“无限循环”,在其中我发出请求,等待响应(最多 10 分钟),从响应中获取一些值并通过将它们存储在某处产生副作用,发出另一个请求。

鉴于我有一些函数调用将启动这个“无限循环”,我还需要返回一个Closable 以满足我正在集成的 Finagle API,以便可以中断该过程。如果 HTTP 请求失败,我需要立即重试。

现在我需要弄清楚如何在 Finagle 中使用 Futures 来实现这一点。我想知道我是否可以通过对响应 Future 应用转换来使用递归?.. 还是我遗漏了一些东西,在 Finagle 中有更直接的方法来做到这一点?

谢谢!

【问题讨论】:

  • 我也遇到过类似的问题,但我已经用 http4s/scalaz-stream time.awakeEvery.map(<do http call>) 解决了。

标签: scala future finagle


【解决方案1】:

我不确定我能否想象它(你所描述的)如何比递归更直接:

  def keepCalling: Future[Unit] = makeRequest
    .flatMap { response => 
       processResponse(response)
       if(cancelled) Future.Unit else keepCalling
     }

请注意,这实际上不是传统意义上的递归,因为我们通常应该期望(有一些保留)在任何给定时间只有一个 keepCalling 实例在堆栈上,因为“递归”调用发生在不同的线程上。

【讨论】:

  • 谢谢!那么,这是否意味着内存消耗会随着每个周期而增长呢?还是 Scala 会解决这个问题?另外,您将如何处理canceledvar?还是有更好的方法来做到这一点?
  • 我没有看到任何关于这种情况的信息表明您应该比任何其他应用程序更担心内存消耗。我的意思是,你确实需要担心它,如果你没有正确释放参考,它增长,我只是不明白为什么这种情况会让你比其他任何人都更担心。至于处理cancelled ...是的,我猜是var。在这样的简单案例中,不需要任何更花哨的东西。请务必将其设为volatile,以便在一个线程中进行的更新能够被另一个线程正确看到。
  • 非常感谢!最后一个问题如果makeRequest 将返回一个失败的未来怎么办? “循环”会刹车吗?我们应该使用其他东西而不是flatMap 来“重试”吗?
  • 当然。您可以在.flatMap 之前插入.rescue.handle 来处理异常。
  • 我最终做了这样的事情:gist.github.com/Ashald/87684ccd50ed66d6ce3b27b4f68fb61b(抱歉,我无法正确地将 sn-p 放入评论中)它看起来合理吗?谢谢!
猜你喜欢
  • 2015-03-09
  • 2019-07-05
  • 2022-01-13
  • 1970-01-01
  • 2018-04-29
  • 2021-09-09
  • 2019-07-21
  • 2015-11-14
  • 2015-10-05
相关资源
最近更新 更多