/ / Реалізація маршрутизації з клієнтами Spray всередині ActorSystem - шкала, маршрутизація, акка, актор, спрей

Впровадження маршрутизації з Spray клієнтів всередині ActorSystem - скала, маршрутизація, акка, актор, спрей

Я "клієнт Spray", який використовується для виклику веб-сервісу REST. В даний час я створюю примірник цього клієнта (використовуючи new GeoSprayWebClient) [див. код нижче] та повторне використання його всередині могосуб'єкти, які роблять запити на REST. Однак жоден екземпляр служби не в змозі впоратися з усім навантаженням. Тому я хочу представити репліки служби REST.

Я новачок у Spray і все ще намагаюся вивчити основи. Мої запитання

1) Я знаю, що спрей внутрішньо використовує акторів Акка. У цьому конкретному випадку я можу отримати ActorRef для клієнтських примірників, щоб я міг створитикілька клієнтських ActorRefs і використовувати їх для створення маршрутизатора Akka. 2) Чи надає клієнтський API Spray якийсь спосіб маршрутизації, який підтримуватиме моє використання?

 import akka.actor.ActorSystem
import spray.client.pipelining._
import spray.http._
import scala.concurrent.Future


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(path) withQuery params
val request = Get(uri)
val futureResponse = pipeline(request)
futureResponse.map(_.entity.asString)
}
}

Відповіді:

0 для відповіді № 1
  1. реалізуйте WebClientActor, який викликає GeoSprayWebClient для виконання вашої роботи.

  2. створити роутер як оброблювач розпилення:

val обробник = context.actorOf ( Реквізити [WebClientActor] .withRouter (RoundRobinRouter (5)), name = "handlerRouter")

  1. надіслати повідомлення обробнику

Таким чином, у нас є 5 екземплярів клієнта, щоб зробити запит.

Я також нова для розпилення, не впевнений, це для вашого призначення чи ні. тільки для вашої інформації.

ура ~!


0 для відповіді № 2

На підставі це Я зміг отримати ActorRef

def createHttpRESTClient(host: String, port: Int): ActorRef = {

// execution context for future transformations below
import system.dispatcher
implicit val timeout: Timeout = 10 seconds

val ref: Future[ActorRef] = for {
Http.HostConnectorInfo(hostConnector: ActorRef, _) <- IO(Http) ? Http.HostConnectorSetup(host, port)
}
yield {
hostConnector
}
//FIXME - TODO fix this it"s really bad. However, We are going to create this only once when we create the actor, so I guess it"s okay for now.
Await.result(ref, 10 seconds)
}

Ось так я надсилаю запит і отримую відповідь від служби за допомогою ActorRef.

  def sendReq(text: String): Future[String] = {
import spray.http._
val params = Map(("key" -> text))
val uri = Uri("/myservice") withQuery params
val request = Get(uri)
//send GET request using the "ask" pattern; the timeout
//TODO - not sure if we can use tell instead of ask here ?
val response: Future[HttpResponse] = restSvrActorRef.ask(request).mapTo[HttpResponse]
log.debug(s"done with sending a request to the REST service")
response.map(_.entity.asString)
}