2013-10-03 148 views
0

我负责的第三方库,它为我提供了异步方法包装的异步调用的过程是这样的:在阿卡演员

def doSomething1(input:String, callback:String => Any) 
def doSomething2(input:Double, callback:String => Any) 

库运行在某个线程的东西它创建。

我想围绕一个演员,所以我可以ask它为垃圾,但我不知道如何获得promise访问,以便我可以满足要求。

简易方法:

class Wrapper extends Actor { 
    def receive { 
    case s:String => doSomething1(s, sender ! _) 
    case d:Double => doSomething2(d, sender ! _) 
    } 
} 

val wrapper = system.actorOf(Props[Wrapper], "wrapper") 

然后ask它的结果:

(wrapper ? "hello").mapTo[String].foreach(println) 
(wrapper ? 123.456).mapTo[String].foreach(println) 

但结果不会回来,大概是因为回调不从演员也ask版的到来。

有没有办法获得promise所以回拨可以success呢?

+0

我可以把它通过存储发送者,告诉回调为目标的包装工作,然后让包装者将消息发送回发件人。 但现在我想知道如果消息回来乱序会发生什么?它如何知道如何匹配它们? – dvmlls

+0

请参阅我对@ yan的回答的评论。 – cmbaxter

回答

0

请注意,我没有测试过这一点,但是这是你在找什么?:

class Wrapper extends Actor { 
    def receive = { 
    case s : String => 
     val response = Promise[String]() 
     val originator = sender 
     doSomething1(s, response.success _) 
     response.future.foreach(originator ! _) 
    case d : Double => 
     val response = Promise[Double]() 
     val originator = sender 
     doSomething2(d, response.success _) 
     response.future.foreach(originator ! _) 
    } 
} 
+0

非常感谢,但我不相信这会有所帮助。在我的情况下,无论第三方库运行的是什么线程都在进行调用,在你的情况下,它是任何线程处理Future,可能是fork连接池。在这两种情况下,阿基岛演员都不会回应。 – dvmlls

+0

@yan,我会帮助你,而不是回答自己,因为你的答案很接近。这里的问题是你正在关闭可变状态,即'sender' ref。在该行下:'val response = Promise [String]()'我会加上:'val originator = sender'。然后调整'foreach'到:'response.future.foreach(originator!_)'。您也可以使用Akka的'pipeTo'模式,而不必处理整个关闭可变状态问题。 – cmbaxter

+0

哦,在'pipeTo'中有魔力,谢谢@cmbaxter – dvmlls