并行运行两个scala函数,5分钟后返回最新值

时间:2016-06-28 01:38:26

标签: scala future

我有两个运行成本很高的Scala函数。每个都像下面一样,他们开始提高变量的值,我想在5分钟(或其他时间)后同时运行它们。我想终止这两个功能并将其最新值提升到那个时间。

function initializeXMLHttpRequest(url) {  //the code that initialize the xhr
    var xhr = new XMLHttpRequest();
    xhr.open('POST', url, true);
    xhr.withCredentials = true;
    xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');

    //set headers
    for (var key in headers) {
        if (headers.hasOwnProperty(key)) {  //filter out inherited properties
            xhr.setRequestHeader(key,headers[key]);
        }
    }

        return xhr;
}

我想知道如何构建我的代码来实现这一点,这里的最佳做法是什么?我正在考虑在超时时在两个不同的线程中运行它们,并在超时时返回它们的最新值。但似乎还有其他方法可以做到这一点。我是Scala的新手,所以任何见解都会非常有用。

3 个答案:

答案 0 :(得分:2)

这并不难。这是一种方法:

  @volatile var terminated = false

  def func1(n: Int): Double = {
    var a = 0.0D
    while (!terminated) {
      a = 0.0001 + a * 0.99999; //some useless formula1
    }
    a
  }

  def func2(n: Int): Double = {
    var a = 0.0D
    while (!terminated) {
      a += 0.0001  //much simpler formula2, just for testing
    }
    a
  }


  def main(args: Array[String]): Unit = {

    val f1 = Future { func1(1) } //work starts here

    val f2 = Future { func2(2) } //and here

    //aggregate results into one common future
    val aggregatedFuture = for{
      f1Result <- f1
      f2Result <- f2
    } yield (f1Result, f2Result)

    Thread.sleep(500) //wait here for some calculations in ms
    terminated = true //this is where we actually command to stop

    //since looping to while() takes time, we need to wait for results
    val res = Await.result(aggregatedFuture, 50.millis)
    //just a printout
    println("results:" + res)

 }

但是,当然,您可能希望查看while循环并创建更易于管理和可链接的计算。

输出:results:(9.999999999933387,31206.34691883926)

答案 1 :(得分:2)

我不是100%确定这是否是你想做的事情,但这是一种方法(不是5分钟,但你可以改变它):

object s
{
    def main(args: Array[String]): Unit = println(run())

    def run(): (Int, Int) =
    {
        val (s, numNanoSec, seedVal) = (System.nanoTime, 500000000L, 0)
        Seq(f1 _, f2 _).par.map(f => 
        {
            var (i, id) = f(seedVal)
            while (System.nanoTime - s < numNanoSec)
            {
                i = f(i)._1
            }
            (i, id)
        }).seq.maxBy(_._1)
    }
    def f1(a: Int): (Int, Int) = (a + 1, 1)
    def f2(a: Int): (Int, Int) = (a + 2, 2)
}

输出:

me@ideapad:~/junk> scala s.scala 
(34722678,2)
me@ideapad:~/junk> scala s.scala 
(30065688,2)
me@ideapad:~/junk> scala s.scala 
(34650716,2)

当然,这一切都假设您至少有两个线程可用于分配任务。

答案 2 :(得分:0)

您可以Future使用Await结果来执行此操作:

  def fun2(): Double = {
    var a = 0.0f
    val f = Future {
      // improve a with algorithm 2 
      a
    }
    try {
      Await.result(f, 5 minutes)
    } catch {
      case e: TimeoutException => a
    }
  }

使用Await.result等待algorithm超时,当我们遇到此超时时,我们直接返回a