2017-01-14 9 views
0

Я написал простого актера, который загружает веб-страницу и отправляет тело этой страницы своему отправителю. Я использую Akka HTTP для создания HTTP-запроса и обработки ответа HTTP. Вот мой код:Akka HTTP отвечает только на 4 запроса

class Downloader(uri: String) extends Actor { 

    import akka.pattern.pipe 
    import context.dispatcher 

    final implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system)) 

    val http = Http(context.system) 
    http.singleRequest(HttpRequest(uri = uri)) pipeTo self 
    println(s"SENDING request to $uri") 

    def receive = { 
    case HttpResponse(StatusCodes.OK, headers, entity, _) => 
     println(s"HttpResponse: SUCCESS") 
     val body = entity.dataBytes.runFold(ByteString(""))(_ ++ _) map (bytes => bytes.decodeString(ByteString.UTF_8)) foreach println 
     sender() ! body 
     context.stop(self) 

    case HttpResponse(code, _, _, _) => 
     println(s"HttpResponse: FAILURE") 
     context.stop(self) 
    } 
} 

В основной программе создать 10 актеров, которые начинают загрузку их веб-страницы в конструкторе.

val system = ActorSystem("akkaHttpClient") 
for (i <- 1 to 10) 
    system.actorOf(Props(classOf[Downloader], "http://akka.io"), s"downloader-$i") 

Thread.sleep(20000) 

val termFuture = system.terminate() 
Await.ready(termFuture, Duration.Inf) 

К сожалению, только 4 из 10 субъектов, созданных получить ответ:

SENDING request to http://akka.io 
SENDING request to http://akka.io 
SENDING request to http://akka.io 
SENDING request to http://akka.io 
SENDING request to http://akka.io 
SENDING request to http://akka.io 
SENDING request to http://akka.io 
SENDING request to http://akka.io 
SENDING request to http://akka.io 
SENDING request to http://akka.io 
HttpResponse: SUCCESS 
HttpResponse: SUCCESS 
HttpResponse: SUCCESS 
HttpResponse: SUCCESS 

Что не так? Я забыл выпустить некоторые ресурсы?

И это правильный подход для загрузки нескольких веб-страниц одновременно с Akka HTTP?

ответ

4

Вы убиваете актера, не ожидая завершения отклика ответа. Ниже следует работать лучше:

def receive = { 
    case HttpResponse(StatusCodes.OK, headers, entity, _) => 
     println(s"HttpResponse: SUCCESS") 
     entity.dataBytes.runFold(ByteString(""))(_ ++ _) map (bytes => bytes.decodeString(ByteString.UTF_8)) foreach { s => 
     println(s) 
     context.stop(self) 
     } 

    case HttpResponse(code, _, _, _) => 
     println(s"HttpResponse: FAILURE") 
     context.stop(self) 
    } 

Почему 4 запроса? 4 - максимальное количество подключений, которое может установить ваш базовый пул подключений клиента, согласно ссылке configuration.