如何在Scala/Akka中处理无限的未来



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

我"解决"了像这样的问题

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

这样我的代码就不会永远被阻塞。然而,我开始通过用简单的Thread.sleep()-存根makeSomeCall()来测试这一点,并发现Await.result实际上并不会扼杀未来,因为测试执行将持续1.minute左右,并随着此参数而变化。我调试了一点,发现实际上Await.result返回,但线程在后台继续,等待Thread.sleep完成。

我假设我的代码只是从当前的Future"分离",并让它在给定的线程中执行——这可能会很快导致生产代码中的一些饥饿。

问题很简单-如何使其正确-这意味着在超时结束后,新线程/Future将被终止,并且该代码分配的所有资源都将被释放(我认为SDK可能会造成一些混乱,但现在这不是问题)

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

总的来说,这是不合理的,因为项目中可能有很多地方在等待同一个未来的结果。

您可以做的是在线程中启动第三方代码,并等待线程在一定时间内完成。如果线程没有在分配的时间内完成,那么您将终止该线程。您可以将此逻辑封装到Promise中,并在第三方代码按时完成时返回成功,或者在必须终止线程时返回超时失败。

也许您应该关注CancellableFutures或InterruptableFutures的实现。以下是VictorKlang关于实现的要点

最新更新