如何处理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 实现
我的问题是 - 我使用 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 实现