我正在处理来自外部系统的连续流消息的Actor系统。我系统中有以下演员。
SubscribeActor
- 此actor订阅Redis频道并创建新的InferActor并将JSON有效负载传递给它。 InferenceActor
- 这位演员负责
2A。解析有效负载并从JSON有效负载中提取一些值文本值。
2B。调用外部REST service
将2a中提取的值传递给此服务。 REST服务部署在LAN中的不同节点上,并且在计算方面做了一些繁重的工作。 使用Spray客户端调用2b中的外部REST服务。我测试了系统,它工作正常,直到2a。但是,只要我介绍2b。我开始出现OutOfMemory错误,系统最终停止运行。
目前,我有两个主要嫌疑人 -
在我去#2之前,我想确保我正确使用Spray客户端,尤其是。当我从其他演员那里调用它时。我的问题是下面的用法正确/不正确/次优?
以下是调用服务的Web服务REST客户端的代码。
trait GeoWebClient {
def get(url: String, params: Map[String, String]): Future[String]
}
class GeoSprayWebClient(implicit system: ActorSystem) extends GeoWebClient {
import system.dispatcher
// create a function from HttpRequest to a Future of HttpResponse
val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
// create a function to send a GET request and receive a string response
def get(path: String, params: Map[String, String]): Future[String] = {
val uri = Uri("http://myhost:9191/infer") withQuery params
val request = Get(uri)
val futureResponse = pipeline(request)
futureResponse.map(_.entity.asString)
}
}
以下是调用上述服务的InferenceActor
代码。
class InferenceActor extends Actor with ActorLogging with ParseUtils {
val system = context.system
import system.dispatcher
val restServiceClient = new GeoSprayWebClient()(system)
def receive = {
case JsonMsg(s) => {
//first parse the message to
val text: Option[String] = parseAndExtractText(s) //defined in ParseUtils trait
log.info(s"extract text $text")
def sendReq(text: String) = {
import spray.http._
val params = Map(("text" -> text))
// send GET request with absolute URI
val futureResponse = restServiceClient.get("http://myhost:9191/infer", params)
futureResponse
}
val f: Option[Future[String]] = text.map(x => sendReq(x))
// wait for Future to complete NOTE: I commented this code without any change.
/* f.foreach { r => r.onComplete {
case Success(response) => log.debug("*********************" + response)
case Failure(error) => log.info("An error has occurred: " + error.getMessage)
}
}
*/
context stop self
}
}
}
答案 0 :(得分:0)
如果您的第二段代码是阻塞的,就像您说的那样,尝试在akka文档Blocking needs careful management中所述的另一个未来包装未来。
它应该限制该请求的资源量。
虽然看起来将text.map转移到不同的演员会更容易。