使用TimeoutException或等待完成未来?

问题描述 投票:0回答:2

我有以下特点:

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
scala future
2个回答
4
投票

选项II通常是首选(或全局设置超时),因为期货通常不是“等待”,而是倾向于链接。

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

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

更常见的是编写代码:

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

2
投票

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

特质我说

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

特质II。说

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

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

© www.soinside.com 2019 - 2024. All rights reserved.