Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Future[Option[Future[Option[Boolean]] Simplifying Futures and Options?

Tags:

scala

akka

I've been trying to simplify the way I do futures in Scala. I got at one point a Future[Option[Future[Option[Boolean]] but I've simplified it further below. Is there a better way to simplify this?

Passing a future of "failed" doesn't seem like the best way to do this. i.e. in the sequential world I simply returned "FAIL!!" any time it failed rather than continuing to the end. Are there other ways?

val doSimpleWork = Future {
  //Do any arbitrary work (can be a different function)
  true //or false
}

val doComplexWork = Future {
  //Do any arbitrary work (can be a different function)
  Some("result") //or false
}

val failed = Future {
  //Do no work at all!!! Just return
  false
}

val fut1 = doSimpleWork
val fut2 = doSimpleWork

val fut3 = (fut1 zip fut2).map({
  case (true, true) => true
  case _ => false
})

val fut4 = fut3.flatMap({
  case true =>
    doComplexWork.flatMap({
      case Some("result") =>
        doSimpleWork
      case None =>
        failed
    })
  case false =>
    failed
})

fut4.map({
  case true =>
    "SUCCESS!!!"
  case _ =>
    "FAIL!!"
})
like image 649
Simon C Avatar asked Apr 30 '13 03:04

Simon C


1 Answers

Note that in your example, because you're eagerly instantiating the Futures to a val, all of them will start executing as soon as you declare them (val x = Future {...}). Using methods instead will make the Futures execute only when they're requested by the chain of execution.

One way to avoid the further computation would be to throw an exception, then handle it with onFailure:

def one = future { println("one") ; Some(1) }
def two = future { println("two") ; throw new Exception("no!"); 2 }
def three = future { println("three") ; 3 }

val f = one flatMap {
  result1 => two flatMap {
    result2 => three
  }
}

f onFailure {
  case e: Exception =>
    println("failed somewhere in the chain")
}

You can see here that "three" isn't supposed to be printed out, because we fail on two. This is the case:

one 
two 
failed somewhere in the chain
like image 171
Alex Yarmula Avatar answered Nov 15 '22 04:11

Alex Yarmula