scala - 如何在 Scala 中为未来添加截止日期?
问题描述
假设我有一个函数fab: A => Future[B]
并希望它返回一个在截止日期之前完成的新未来。所以我正在写一个这样的新deadlined
函数
def deadlined[B](fut: => Future[B], deadline: Deadline): Future[B] = ???
现在我正在使用java.util.Timer
但可以ScheduledThreadPoolExecutor
按照建议使用。最好的解决方案可能是一个包装器,用于抽象调度实现并按照评论中的建议在测试中模拟它。
object Deadlined {
private val timer = new java.util.Timer() // todo: replace it with a wrapper
def apply[B](fut: => Future[B], deadline: Deadline)(implicit ec: ExecutionContext): Future[B] = {
val promise = Promise[B]()
val timerTask = new java.util.TimerTask {
override def run(): Unit = promise.failure(new Exception(s"$deadline is exceeded"))
}
timer.schedule(timerTask, deadline.timeLeft.toMillis)
fut.transform { result =>
timerTask.cancel()
result match {
case Success(b) => promise.success(b)
case Failure(t) => promise.failure(t)
}
result
}
promise.future
}
}
是否有意义 ?我还想知道如何从对我之前的问题的回答中找出一个共同的部分Deadlined
和延迟。
解决方案
我可能会做类似于以下的事情,所以我可以为任何 Future(YMMV、Caveat Emptor 等)添加截止日期:
import scala.concurrent.{Future, ExecutionContext}
import scala.concurrent.duration.FiniteDuration
import java.util.{Timer, TimerTask}
implicit class DeadlineFuture[T](future: Future[T]) {
def deadline(d: FiniteDuration)(implicit timer: Timer): Future[T] = {
if (future.isCompleted) future
else {
val promise = Promise[T]()
val timerTask = new TimerTask {
override def run(): Unit = promise.tryFailure(new Exception(s"$d is exceeded"))
}
timer.schedule(timerTask, d.toMillis)
future.onComplete(_ => timerTask.cancel())(ExecutionContext.parasitic)
promise.completeWith(future).future
}
}
}
// Usage:
Future.never.deadline(5.seconds).onComplete(println)
推荐阅读
- c - 使用clang编译c文件时出错?
- android - Android kotlin WorkManger 不返回 Worker.Result.FAILURE
- php - 如何在离子插件中进行指纹存储?
- windows - Windows,服务删除后无法立即删除文件
- python - pandas Grouper 中的异常记忆问题
- docker - Docker 远程解释器未出现在最新的 PhpStorm 中
- groovy - Groovy模板引擎在java中转义括号
- pivot - Talend Pivoting 并将数据保存到另一个表中
- javascript - 如何在 Puppeteer 中设置最大视口?
- maven - 使用 spring-boot-maven-plugin 重新打包创建 uber jar 失败