如何处理Scala/Akka中的无限Future?

How to deal with infinite Future in Scala/Akka?

我的问题是 - 我使用 Scala 和 Akka - 其中一项工作是通过第三方 SDK 使用外部 API。问题是我无法控制这个 SDK,好吧,我应该预料到里面会发生任何事情,甚至是无限循环。

我"solved"这个问题

Await.result( Future { sdk.makeSomeCall()}, 1.minute)

所以我的代码不会永远阻塞。但是,我开始通过用简单的 Thread.sleep() 存根 makeSomeCall() 来测试它 - 发现 Await.result 实际上并没有杀死未来,因为测试执行持续了大约 1.minute 并且使用此参数更改。 我调试了一下,发现实际上 Await.result returns,但是线程在后台继续,等待 Thread.sleep 完成。

我假设我的代码只是 'detach' 来自当前的 Future 并让它在给定的线程中执行 - 这可能会很快导致生产代码中的一些饥饿。

问题很简单 - 如何让它正确 - 这意味着在超时过后新的 thread/Future 将被终止并且这段代码分配的所有资源将被释放(我假设 SDK 可能会做一些一团糟,但这现在不是问题)

我认为您的假设是正确的,即 Await.result 不会 "kill" 未来。 await 限制了等待代码等待的时间,它根本不限制为未来提供结果的代码。

这在一般情况下是不合理的,因为程序中可能有很多地方等待同一个 future 的结果。

您可以做的是在线程中启动第 3 方代码并等待线程在时限内完成。如果线程没有在分配的时间内完成,您将终止该线程。您可以将此逻辑包装到一个 Promise 中,然后 return 要么成功(第 3 方代码按时完成),要么超时失败(当您不得不终止线程时)。

您可能应该查看 CancellableFutures 或 InterruptibleFutures 的实现。 这是来自 VictorKlang 的 gist 实现