Akka 在参与者中使用spray客户端(sendReceive)

Akka 在参与者中使用spray客户端(sendReceive),akka,actor,spray,spray-client,Akka,Actor,Spray,Spray Client,用例如下所示: 参与者被绑定到spray IO—接收和处理通过指定端口发出的所有入站HTTP请求 对于每个入站请求,参与者需要向不同的外部端点发送出站异步http请求,获取入站响应并将响应发送回发起方 使用spray的客户端sendReceive返回未来。这意味着参与者将继续处理其邮箱上的下一个入站邮件,而不等待其刚刚发送的出站请求的响应,同时出站请求的响应可能会到达并在将来的回调中执行,由于它没有在参与者的邮箱上排队,因此可能会并行执行,打破了参与者在给定时间内仅由一个线程执行的想法 我想知道

用例如下所示:

  • 参与者被绑定到spray IO—接收和处理通过指定端口发出的所有入站HTTP请求
  • 对于每个入站请求,参与者需要向不同的外部端点发送出站异步http请求,获取入站响应并将响应发送回发起方
  • 使用spray的客户端sendReceive返回未来。这意味着参与者将继续处理其邮箱上的下一个入站邮件,而不等待其刚刚发送的出站请求的响应,同时出站请求的响应可能会到达并在将来的回调中执行,由于它没有在参与者的邮箱上排队,因此可能会并行执行,打破了参与者在给定时间内仅由一个线程执行的想法


    我想知道如何在不破坏actor线程封装的情况下处理这个用例,actor如何以actor安全的方式使用spray客户端(用于发送/接收异步http事件?

    完全可以安全地完成未来,而不是
    spray routing
    中的实际值,因此,例如,您可以执行以下操作:

    get {
        comlete {
            val resultFuture: Future[Result] = ...
    
            val resultFuture.onComplete {....}
    
            resultFuture
        }
    }
    

    当然,您还需要确保处理超时和错误情况。

    问题是哪个线程执行回调,如果回调未在参与者邮箱中排队,则可能是与参与者接收处理并行执行,这可能会破坏其线程封装

    据我所知,akka actor'ask'方法也存在同样的问题,它返回一个Future,它们提供了一个警告,不要在回调中对actor的可变状态执行操作,因为这可能会导致同步问题。见:

    “警告: 在使用将来的回调时,例如onComplete、onSuccess和onFailure,在actor内部,您需要小心避免关闭包含actor的引用,即不要从回调中调用方法或访问封闭actor上的可变状态。这将破坏actor封装,并可能引入同步错误和错误ace条件,因为回调将被并发地调度到封闭的参与者。不幸的是,还没有一种方法可以在编译时检测这些非法访问。”