在Scala中定期调用一个函数,而另一个昂贵的函数正在计算

时间:2018-10-21 07:08:06

标签: multithreading scala design-patterns concurrency

我有一个需要很长时间才能计算的函数

def longFunc = {Thread.sleep(30000); true}

此函数正在计算时,我需要对服务器进行ping操作,以便它一直在等待我的函数的值。但是为了论证,假设我需要在longFunc运行时每5秒运行以下函数

def shortFunc = println("pinging server! I am alive!")

为此,我有以下代码片段,它可以工作,但我想知道这种情况下是否有更好的模式

import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import java.util.{Timer, TimerTask}
import scala.concurrent.ExecutionContext.Implicits.global

def shortFunc = println("pinging server! I am alive!")
def longFunc = {Thread.sleep(30000); true}

val funcFuture = Future{longFunc}

val timer = new Timer()
def pinger = new TimerTask {
        def run(): Unit = shortFunc
}

timer.schedule(pinger, 0L, 5000L) // ping the server every two minutes to say you are still working
val done = Await.result(funcFuture, 1 minutes)
pinger.cancel 

1 个答案:

答案 0 :(得分:1)

我实际上不确定这是更优雅的模式还是只是为了好玩:

import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

def waiter[T](futureToWait:Future[_], waitFunc: => T, timer: Duration) = Future {
  while (!futureToWait.isCompleted) {
    Try(Await.ready(futureToWait, timer))
    waitFunc
  }
}

def longFunc = {Thread.sleep(30000); true}
def shortFunc = println("pinging server! I am alive!")

val funcFuture = Future{longFunc}
waiter(funcFuture,shortFunc,5 second)

val done = Await.result(funcFuture, 1 minutes)

相同但更短:

import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

def longFunc = {Thread.sleep(30000); true}
def shortFunc = println("pinging server! I am alive!")

val funcFuture = Future{longFunc}

def ff:Future[_] = Future{
  shortFunc
  Try(Await.ready(funcFuture, 5 second)).getOrElse(ff)
}
ff

val done = Await.result(funcFuture, 1 minutes)