1

用例是这样的:

  1. 一个 Actor 绑定到喷 IO - 接收和处理所有通过指定端口的入站 HTTP 请求。
  2. 对于每个入站请求,参与者需要将出站异步 http 请求发送到不同的外部端点,取回入站响应并将响应发送回发起方。

使用 spray 的客户端 sendReceive 返回一个未来。这意味着参与者将继续处理其邮箱中的下一条入站消息,而无需等待它刚刚发送的出站请求的响应,同时出站请求的响应可能会到达并在 Future 回调中执行,因为它是没有在actor的邮箱中排队,它可能会被并行执行,打破了actor在给定时间内仅由一个线程执行的想法。

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

4

2 回答 2

0

问题是哪个线程执行回调,如果它没有在actor的邮箱中排队,它可能是actor接收处理的并行执行,这可能会破坏它的线程封装......

据我了解,返回 Future 的 akka actor 'ask' 方法存在相同的问题,它们提供警告,不要从回调中对 actor 的可变状态执行操作,因为它可能会导致同步问题。见:http ://doc.akka.io/docs/akka/snapshot/scala/actors.html

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

于 2015-02-05T14:39:45.757 回答
0

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

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

        val resultFuture.onComplete {....}

        resultFuture
    }
}

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

于 2015-02-05T14:09:40.937 回答