0
votes

I have setup a play 2.5 project with heavy database access using Ebean. i configure hikaricp to maximumPoolSize=100 and minimumIdle=100 and hikaricp pool 100 connection successfully and i also configure thread pool like this:

akka {
  actor {
    default-dispatcher {
      executor = "thread-pool-executor"
      throughput = 1
      thread-pool-executor {
        fixed-pool-size = 109 # db conn pool (100) + number of cores (8) + housekeeping (1)
      }
    }
  }
}

I implement async action using CompletionStage:

public CompletionStage<Result> asyncDb() {
    CompletableFuture<Integer> future = new CompletableFuture<>().supplyAsync(() -> {
        Ebean.createSqlQuery("select sleep(3)").findUnique();
        return 0;
    });

    return future.thenApplyAsync(integer -> ok("done"));
}

I run system using sbt start and test it using apache benchmark:

ab -n 10000 -c 100 -r -k http://localhost:9000/asyncDb

The problem is play only use 7 or 8 connection from pool and other mysql connection are idle meanwhile there are request, why?

1

1 Answers

0
votes

Greg Methvin answered my question in play google group : I think the problem is that CompletableFuture.supplyAsync does not use the default dispatcher. It's instead using ForkJoinPool.commonPool(). (See this link)

You need to use the version that accepts an executor

For the executor you actually have two options:

  1. Pass the ActorSystem to your controller and call actorSystem.dispatcher(), and configure it as you did above, or

  2. Create a separate executor with 100 threads specifically for your database, and keep the default executor for processing requests.

Check out the documentation here for different options re thread pools: