Search code examples
multithreadingscalaplayframeworknonblocking

Play! Framework: Limit concurrent non-blocking IO calls made via WS


I have been using Play!Framework's WS to make network calls. Say I have 5 threads in a custom ExecutionContext within the scope. If I were to push blocking network call, at most 5 parallel requests can be handled so explicitly I am able to limit amount of network calls done at once.

When using WS, this is not the case. It will make network calls beyond 5 threads, since it does not block in the custom pool which is making the WS request. What I am observing is that I can make as many requests as I want and eventually overwhelm the OS resource. The sample code can be found below. Nested calls makes 100 * 100 = 10000 calls in total. My question is, is there a way to limit how many calls can happen in parallel for WS (non-blocking IO)? Only way I can think of is load balancing before requests gets to the server. Thanks!

val cols = (1 to 100).map { col =>
  ws.url(s"http://get-resource/${col}").get().flatMap { futureColResp =>
    val outerCol = futureColResp.json

   val rowFutures = (1 to 100).map { row =>
      ws.url(s"http://get-resource/${row}").get().map { futureRowResp =>
        val innerRow = futureRowResp.json
        doSomething(outerCol, innerRow)
      }
   }
    Future.sequence(rowFutures)
  }
}
Future.sequence(cols)

Solution

  • In play's configuration, you can set the following setting: play.ws.ahc.maxConnectionsTotal

    Described here: https://www.playframework.com/documentation/2.5.x/ScalaWS#configuring-asynchttpclientconfig

    Once, the number of concurrent outgoing connections exceeds the defined value, Play application will not create new connection to the target and throw below exception: play.shaded.ahc.org.asynchttpclient.exception.TooManyConnectionsException: Too many connections: 5

    A better behaviour in this case might be to reduce the parallelism to avoid running out of resource or to reduce the number of requests to the same server if possible (can they be batched?).