Browse Source

Merge pull request #96 from huntc/connection-pooling

Beginnings of connection pooling configuration.
Patrick Falls 12 năm trước cách đây
mục cha
commit
fc60d2a2fc

+ 14 - 3
play-java/app/controllers/Application.java

@@ -1,6 +1,9 @@
 package controllers;
 
+import akka.dispatch.Futures;
 import models.World;
+import play.api.libs.concurrent.Promise;
+import play.libs.Akka;
 import play.libs.F;
 import play.libs.Json;
 
@@ -10,6 +13,7 @@ import org.codehaus.jackson.node.ObjectNode;
 import org.codehaus.jackson.map.ObjectMapper;
 import play.mvc.Controller;
 import play.mvc.Result;
+import scala.concurrent.ExecutionContext;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -22,10 +26,12 @@ public class Application extends Controller {
 
     private static final int TEST_DATABASE_ROWS = 10000;
     //http://stackoverflow.com/questions/3907929/should-i-make-jacksons-objectmapper-as-static-final
-    private static final ObjectMapper objectMapper = new ObjectMapper();
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+    private static final ExecutionContext DB_EC = Akka.system().dispatchers().lookup("akka.actor.db");
 
     public static Result json() {
-        final ObjectNode result = objectMapper.createObjectNode();
+        final ObjectNode result = OBJECT_MAPPER.createObjectNode();
         result.put("message", "Hello World!");
         return ok(result);
     }
@@ -38,7 +44,12 @@ public class Application extends Controller {
                         final Random random = ThreadLocalRandom.current();
                         final List<F.Promise<? extends World>> promises = new ArrayList<F.Promise<? extends World>>(queries);
                         for (int i = 0; i < queries; ++i) {
-                            promises.add(future(findWorld(Long.valueOf(random.nextInt(TEST_DATABASE_ROWS) + 1))));
+                            // There's no convenience method for submitting a future on an EC in Java. There is
+                            // an issue that will address this though: https://github.com/playframework/Play20/issues/972
+                            // Meanwhile we call the Akka future directly and wrap its result in a promise.
+                            final F.Promise p = Akka.asPromise(Futures.future(
+                                    findWorld(Long.valueOf(random.nextInt(TEST_DATABASE_ROWS) + 1)), DB_EC));
+                            promises.add(p);
                         }
                         final List<World> worlds = F.Promise.sequence(promises).get(5L * queries, TimeUnit.SECONDS);
                         return ok(Json.toJson(worlds));

+ 14 - 3
play-java/conf/application.conf

@@ -35,17 +35,17 @@ db.default.user=benchmarkdbuser
 db.default.password=benchmarkdbpass
 db.default.jndiName=DefaultDS
 
-db.default.partitionCount=2
+db.default.partitionCount=4
 
 # The number of connections to create per partition. Setting this to 
 # 5 with 3 partitions means you will have 15 unique connections to the 
 # database. Note that BoneCP will not create all these connections in 
 # one go but rather start off with minConnectionsPerPartition and 
 # gradually increase connections as required.
-db.default.maxConnectionsPerPartition=5
+db.default.maxConnectionsPerPartition=64
 
 # The number of initial connections, per partition.
-db.default.minConnectionsPerPartition=5
+db.default.minConnectionsPerPartition=64
 
 # Evolutions
 # ~~~~~
@@ -87,6 +87,17 @@ play {
           parallelism-max = 300
         }
       }	
+      db = {
+        executor = "thread-pool-executor"
+        thread-pool-executor {
+          core-pool-size-factor = 1.0
+          core-pool-size-min = 256
+          core-pool-size-max = 256
+          max-pool-size-factor = 1.0
+          max-pool-size-min = 256
+          max-pool-size-max = 256
+        }
+      }
     }
   }
 }

+ 6 - 3
play-scala/app/controllers/Application.scala

@@ -1,6 +1,6 @@
 package controllers
 
-import play.api._
+import play.api.Play.current
 import play.api.mvc._
 import play.api.libs.json.Json
 import play.api.libs.concurrent._
@@ -12,6 +12,8 @@ object Application extends Controller {
   
   private val TEST_DATABASE_ROWS = 10000
 
+  private val dbEc = Akka.system.dispatchers.lookup("akka.actor.db")
+
   def json() = Action {
     Ok(Json.obj("message" -> "Hello World!"))   
   }
@@ -23,8 +25,9 @@ object Application extends Controller {
       val random = ThreadLocalRandom.current()
 
       val worlds = Future.sequence( (for {
-        _ <- (1 to queries).par
-      } yield Future(World.findById(random.nextInt(TEST_DATABASE_ROWS) + 1))).toList)
+            _ <- 1 to queries
+          } yield Future(World.findById(random.nextInt(TEST_DATABASE_ROWS) + 1))(dbEc)
+        ).toList)
 
       worlds map {
         w => Ok(Json.toJson(w))  

+ 14 - 3
play-scala/conf/application.conf

@@ -36,17 +36,17 @@ db.default.user=benchmarkdbuser
 db.default.password=benchmarkdbpass
 db.default.jndiName=DefaultDS
 
-db.default.partitionCount=2
+db.default.partitionCount=4
 
 # The number of connections to create per partition. Setting this to 
 # 5 with 3 partitions means you will have 15 unique connections to the 
 # database. Note that BoneCP will not create all these connections in 
 # one go but rather start off with minConnectionsPerPartition and 
 # gradually increase connections as required.
-db.default.maxConnectionsPerPartition=5
+db.default.maxConnectionsPerPartition=64
 
 # The number of initial connections, per partition.
-db.default.minConnectionsPerPartition=5
+db.default.minConnectionsPerPartition=64
 
 # Evolutions
 # ~~~~~
@@ -82,6 +82,17 @@ play {
           parallelism-max = 300
         }
       }
+      db = {
+        executor = "thread-pool-executor"
+        thread-pool-executor {
+          core-pool-size-factor = 1.0
+          core-pool-size-min = 256
+          core-pool-size-max = 256
+          max-pool-size-factor = 1.0
+          max-pool-size-min = 256
+          max-pool-size-max = 256
+        }
+      }
     }
   }
 }