在Scala 2.10中终止或超时未来

在Scala 2.10中终止或超时未来,scala,timeout,future,scala-2.10,Scala,Timeout,Future,Scala 2.10,嗨 我正在将Scala2.10与新的futures库一起使用,并试图编写一些代码来测试无限循环。我使用scala.concurrent.Future在单独的线程中运行循环代码。然后,我想等待一段时间来做一些测试,然后终止单独的线程/未来。我已经看过了《等待结果》,但这并没有扼杀未来。有没有办法让新的Scala 2.10版本暂停或终止 我不希望只为这个简单的部分添加外部依赖项,如Akka。否-您必须添加一个循环检查的标志。如果设置了该标志,则停止循环。确保该标志至少是易变的 参见第135-137页

我正在将Scala2.10与新的futures库一起使用,并试图编写一些代码来测试无限循环。我使用
scala.concurrent.Future
在单独的线程中运行循环代码。然后,我想等待一段时间来做一些测试,然后终止单独的线程/未来。我已经看过了《等待结果》,但这并没有扼杀未来。有没有办法让新的Scala 2.10版本暂停或终止


我不希望只为这个简单的部分添加外部依赖项,如Akka。

否-您必须添加一个循环检查的标志。如果设置了该标志,则停止循环。确保该标志至少是易变的

参见第135-137页。

不要在家里尝试

import scala.concurrent._
import scala.concurrent.duration._

class MyCustomExecutionContext extends AnyRef with ExecutionContext {
  import ExecutionContext.Implicits.global
  @volatile var lastThread: Option[Thread] = None
  override def execute(runnable: Runnable): Unit = {
    ExecutionContext.Implicits.global.execute(new Runnable() {
      override def run() {
        lastThread = Some(Thread.currentThread)
        runnable.run()
      }
    })
  }
  override def reportFailure(t: Throwable): Unit = ???
}    

implicit val exec = new MyCustomExecutionContext()
val f = future[Int]{ do{}while(true); 1 }
try {
  Await.result(f, 10 seconds) // 100% cpu here
} catch {
  case e: TimeoutException => 
    println("Stopping...")
    exec.lastThread.getOrElse(throw new RuntimeException("Not started"))
      .stop() // 0% cpu here
}

我遇到了类似的问题,并编写了以下非阻塞未来操作:

class TerminationToken(var isTerminated: Boolean)
object TerminationToken { def apply() = new TerminationToken(false) }

 implicit class FutureOps[T](future: Future[Option[T]]) {
 def terminate(timeout: FiniteDuration, token: TerminationToken): Future[Option[T]] = {
   val timeoutFuture = after[Option[T]](timeout, using = context.system.scheduler) {
     Future[Option[T]] { token.isTerminated = true; None } }
          Future.firstCompletedOf[Option[T]](Seq (future recover { case _ => None }, timeoutFuture))
     }
   }

然后创建一个返回选项的期货,并在其上使用.terminate(超时,令牌)

不需要Akka-实际上,Akka在2.1之后没有期货。Akka的未来转移到scala.concurrent。Viktor Klang的这篇博文相关:(不确定年份:2017?2018?)一想到这我就心惊肉跳。不用担心。使用
中断
然后
等待
一段时间,然后使用
if(thread.isAlive)
do
connection.close()
停止
作为最后手段。客户从来没有听从过我,因为他们能够以这种方式打断长时间的询问=)我希望有一个稍微优雅一点的解决方案:)。在我看来,这是你经常想做的事情。我会把这个问题留一段时间,希望在我接受之前有人能想出更好的答案。我建议1)使用
while(!terminated)
,就像
sourcedelica
的答案一样,2)围绕
原子引用
-s对需要关闭的资源创建未来的关闭,然后在完成时关闭它们,和超时。