Akka Http singleRequest stream is hanging after multiple requests

1.2k views Asked by At

I'm trying to request multiple links, one at a time using akka-https Http().singleRequest. In my demo code below however the foldLeft only ever loops four times and the application never reaches the println statements or terminates.

Im using the default akka config, but I'm thinking that the Http().singleRequest is consuming my threads and not releasing them. If I change the link list to only include 4 links the application terminates and I can see the println. However five and the app will hang during the fifth loop.

Has anyone seen this before or is there a fault with my impl. of the ActorSystem in this specific usecase.

val links = List(
  "https://www.google.com/",
  "https://www.google.com/",
  "https://www.google.com/",
  "https://www.google.com/",
  "https://www.google.com/",
  "https://www.google.com/",
  "https://www.google.com/",
  "https://www.google.com/"
)

implicit val as: ActorSystem = ActorSystem()
implicit val mat: ActorMaterializer = ActorMaterializer()

import as.dispatcher

def get(url: String): Future[Either[Throwable, Unit]] = {
  Http().singleRequest(HttpRequest(uri = url)) transformWith {
    case Success(_) =>
      Future.successful(Right(()))
    case Failure(e) =>
      Future.successful(Left(e))
  }
}

def getLinks(): Future[Seq[Unit]] = {
  links.foldLeft(Future.successful(Seq.empty[Unit])){
    case (f, e) => f.flatMap { ls =>
      get(e) map {
        case Right(i) => ls :+ i
        case Left(_) => ls
      }
    }
  }
}

getLinks() transformWith{
  case Success(ls) =>
    println("terminated")
    println(ls.length)
    Future.successful(())
  case Failure(e) =>
    println("terminated")
    println(e.getMessage)
    Future.successful(())
}
1

There are 1 answers

1
kardapoltsev On BEST ANSWER

Consuming (or discarding) the Entity of a request is mandatory (from https://doc.akka.io/docs/akka-http/current/implications-of-streaming-http-entity.html).

Try to add response.discardEntityBytes() to your code.