0

I'm setting up a new rest server using TwitterServer, and it seems to block a new api call, till a previous one be finished.

Here is a simple modification of the basic code taken from the documentation at https://twitter.github.io/twitter-server :

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http.{Request, Response, Status}
import com.twitter.server.TwitterServer
import com.twitter.util.{Await, Future, FuturePool}

object BasicServer extends TwitterServer {
  val service = new Service[Request, Response] {
    def apply(request: Request): Future[Response] = {
      FuturePool.unboundedPool {
        Thread.sleep(10000)

        val response = Response(request.version, Status.Ok)
        response.contentString = "hello"

        response
      }
    }
  }

  def main(): Unit = {
    val server = Http.serve(":8888", service)
    onExit {
      server.close()
      ()
    }
    Await.ready(server)

    ()
  }
}

if i try to do multiple calls to http://localhost:8888, the first call blocks the second one, for some reason. Any idea why is this happening ?

eran
  • 21
  • 3
  • What do you mean by "blocks the second one". All your requests should be able to be processed in parallel but they, indeed take 10s each. Are you seeing something else? How are you issuing requests? – Vladimir Kostyukov Apr 30 '19 at 17:24
  • Just open two tabs in the browser, and navigate to http://localhost:8888 on both of them on the same time. The first will return after 10 seconds, and the second after 20 seconds. Both of them should return after 10 seconds. Can be done with obviously with curl as well. – eran Apr 30 '19 at 17:47
  • Maybe your browser has a limit on the number of concurrent connections? Can you use test it with curl instead? See more at https://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser – Vladimir Kostyukov Apr 30 '19 at 18:39
  • I just checked Chrome and it indeed serializes these requests. Curl/HTTPie (CLI tools) send these in parallel and all requests complete in 10s as expected. – Vladimir Kostyukov Apr 30 '19 at 18:49
  • But the all idea of finagle is the parallelism... And it doesnt seem to work at chrome ?! – eran Apr 30 '19 at 18:55
  • It's not a Finagle's fault. It's Chrome queueing your requests to the same host. Finagle only sees one at a time. – Vladimir Kostyukov Apr 30 '19 at 19:01
  • Also, try Firefox. It's our recommended stress-test browser for Finagle. – Vladimir Kostyukov Apr 30 '19 at 19:11
  • it seems that chrome, postpone the second query, because it is the same as the first one. if we differentiate (by some param, by example), chrome make the two calls at the same time. – eran May 02 '19 at 13:31

1 Answers1

1

You should NOT use Thread.sleep with Finagle (nor with any other non-blocking solution) ... most of those solutions count with the fact that the threads are not blocked long.

Thread.sleep is using any local thread to sleep on it and that will block the poor server without further notice.

As a soluion for a sleep, please use the Future.sleep like in:

import com.twitter.conversions.DurationOps._ // for the 5.seconds part to work
import com.twitter.util._

implicit val twitterTimer = new ScheduledThreadPoolTimer // for the sleep time to work

Future.sleep(5.seconds) flatMap FuturePool.unboundedPool { ...(and remove the Thread.sleep inside) ... }
Carlos Saltos
  • 1,385
  • 15
  • 15