我的问题是-我使用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关于实现的要点