在Java中使用Await in Chained Akka Futures

时间:2017-07-10 21:11:41

标签: java asynchronous akka future

我正在尝试构建FutureBuilder类,以简化链接期货。在此过程中,我试图了解使用Await的后果。

所以如果我有Mappers就是这样的话  F1(future1) - > F2 - > F3

F1:构建对象Foo

F2:转到数据库,将值Bar添加到Foo

F3:将包含Foo的消息发送到其他地方

我遇到的问题是F2,通常我会创建一个Future来从DB中获取Bar。在这种情况下,我已经在未来,所以在子未来上只有Await.result()更容易,这样我就可以立即将它添加到Foo并将其传递给F3。 / p>

有问题吗?既然我将来会等待,我会通过等待锁定一个额外的线程吗?

OR是否应该完全采用不同的模式?请记住,我希望能够继续前进,以便在映射器中传递Foo对象,以便我可以轻松添加F4,5,6等。我知道我也可以将F3移动到F2并使用DB请求进行映射,但这也意味着我必须移动F4,5,6等。用它?

2 个答案:

答案 0 :(得分:0)

  

有问题吗?因为我是将来的,所以我通过等待锁定一个额外的线程?

是的,你阻止了一个额外的线程: http://doc.akka.io/docs/akka/current/java/futures.html#use-with-actors

  

警告

     

Await.result和Await.ready是为必须阻止的特殊情况提供的,一个好的经验法则是只有在你知道必须阻止的情况下才使用它们。

我只在测试代码中使用Await。

该文件中的以下部分描述了如何将期货连在一起。如果您可以使用Java 8,它会变得更好,本节详细信息:

http://doc.akka.io/docs/akka/current/java/futures.html#java-8-completionstage-and-completablefuture

答案 1 :(得分:0)

如果对象构造涉及多个阶段和多个阻塞调用,如DB调用,如果阻塞调用真的是一个关注点,而不是链接多个未来,我想知道为什么不使用actor。 Foo可以成为演员的状态。

object Data {
    case class Foo(var1: String, var2: String, ..)

    // commands or messages 
    case object doF1
    case object doF2
    //...
}

class FutureChainAlternative extends Actor {
    def receive = {
        case doF1 =>
            // perform what F1 should do.
            // pipe the result back to self
            f1.map(f1Result => preferredFormatConvertorOrProcessorForF1) pipeTo self         

         case preferredFormatConvertorOrProcessorF1 =>
            // update the Foo object with F1 results
            self ! doF2   

         case doF2 =>
            // perform what F2 should do.
            // pipe the result back to self
            f2.map(f2Result => preferredFormatConvertorOrProcessorForF2) pipeTo self    
    }
}

为什么我们需要一个单独的消息preferredFormatConvertorOrProcessorF1? 完成后的F1将在一个单独的线程中解决。我们无法在另一个线程中更新actor状态。 (众所周知关闭问题)

<强>超时 如果你需要在特定时间范围内发生的事情。 Ask模式结合Pipe模式将起到魔力。