1

I am using twitter finagle framework and given a sequence of future of optionals I would like to filter them based on the state of the option.

seqFuture : Seq[Future[Option[Foo]]] 
val filteredFuture = seqFuture map { fut => fut map {
      opt => if(opt.isDefined) bar(opt.get)
   }
}

The function bar : Foo => Bar could be identity, but I do not want to return an Option[Bar]. If the option is not defined I want the future to silently fail and only chain further processing on the futures that contain a defined option.

I have tried a combination of flatten, flatMap, match case Some(_) =>, but I do not arrive at filtering them. If I throw an Exception where the option is not defined all of the futures processing will fail (since I collect them at some point)

I could not find any solution to this problem in finagle guide

Alternative solutions to filter and chaining futures using the finagle framework would still be appreciated.

4

1 回答 1

5

The problem with the two layers of map here (first the Seq, then the Future) is that this approach doesn't allow you to "skip" the futures that compute empty options.

If you use Future.collect (note that the standard library and other APIs call this operation sequence), you can do this as a one-liner, and also end up with a Future[Seq[...]], which is almost always a nicer thing to have than a Seq[Future[...]]:

def filteredFuture: Future[Seq[Foo]] = Future.collect(seqFuture).map(_.flatten)

If you really need to go from a Seq[Future[Option[Foo]]] to a Seq[Future[Foo]] (instead of the Future[Seq[Foo]] you get from collect), you're kind of out of luck. You could do it if you're willing to have any None values result in failed futures, but these will blow up when you call something like collect down the line, and if you want them to be silently ignored, you'll have to handle those failures explicitly. I'd strongly suggest using Future.collect and going directly to the Future[Seq[Foo]].

于 2019-02-27T13:42:35.250 回答