使用TimeoutException或等待完成未来?

时间:2018-05-14 10:05:52

标签: scala future

我有以下特点:

trait Tr{
     /**
      * Returns future of the number of bytes written
      */
     def write(bytes: Array[Byte]): Future[Long]
}

所以我可以等待这样的结果:

予。

val bts: Array[Byte] = //...
val to: Long = //...
val tr: Tr = //...
Await.result(tr.write(bts), to)

但我也可以用不同的方式设计Tr

trait Tr{
     /**
      * Returns future of the number of bytes written
      */
     def write(bytes: Array[Byte], timeout: Long): Future[Long]
}

II。

val bts: Array[Byte] = //...
val to: Long = //...
val tr: Tr = //...
Await.result(tr.write(bts, to), Duration.Inf)

更好的方法是什么?我认为 II 案例可用于实际写入IO不可中断或由调用者线程执行的情况。因此,为了灵活性,我会以 II 的方式设计线程。

II 看起来有点奇怪。

这样做是否正确?或者我滥用Future

更新:考虑Tr的以下可能实现:

class SameThreadExecutionContext extends ExecutionContext{
  override def execute(runnable: Runnable): Unit = runnable.run()
  override def reportFailure(cause: Throwable): Unit = ???
}

clas DummyTrImpl extends Tr{
    private final implicit val ec = new SameThreadExecutionContext
    override def write(bytes: Array[Byte]): Future[Long] = {
         Thread.sleep(10000)
         throw new RuntimeException("failed")
    }
}

现在如果我写这个:

val bts: Array[Byte] = //...
val to: Long = 1000
val tr: Tr = new DummyTrImpl
Await.result(tr.write(bts), to) //Waiting 10 secs instead of 1 
                                //and throwing RuntimeException instead of timeout

2 个答案:

答案 0 :(得分:4)

选项II通常是首选(或全局设置的超时),因为期货通常不会等待#34;但往往会被链接。

编写如下代码是不常见的:

Await.result(tr.write(bts, to))

更常见的是编写代码:

tr.write(bts, to).then(written => ... /* write succeeded, do next action */ ..)

答案 1 :(得分:2)

这两个特征有不同的行为,所以它取决于你想要达到的目标。

特质 我。

  

写一些数据,并根据需要采取。写入完成或失败时完成Future

特质 II。

  

尝试写一些数据,但如果花费太长时间就会放弃。写入完成,失败或超时

时完成Future

第二个选项是首选,因为它可以保证进展,并且如果write超时,Await.result不会挂起。