Browse Source

Merge pull request #4413 from mkurz/PlayResources

Play 2: Adjust thread pool/db pool size to CPU's available
Mike Smith 6 years ago
parent
commit
71e20c377e
48 changed files with 517 additions and 61 deletions
  1. 1 1
      frameworks/Java/play2-java/play2-java-ebean-hikaricp-netty.dockerfile
  2. 1 1
      frameworks/Java/play2-java/play2-java-ebean-hikaricp.dockerfile
  3. 30 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/startup/Startup.java
  4. 18 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/startup/StartupModule.java
  5. 9 6
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/application.conf
  6. 1 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/logback.xml
  7. 1 1
      frameworks/Java/play2-java/play2-java-jooq-hikaricp-netty.dockerfile
  8. 1 1
      frameworks/Java/play2-java/play2-java-jooq-hikaricp.dockerfile
  9. 30 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/startup/Startup.java
  10. 18 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/startup/StartupModule.java
  11. 9 6
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/application.conf
  12. 1 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/logback.xml
  13. 1 1
      frameworks/Java/play2-java/play2-java-jpa-hikaricp-netty.dockerfile
  14. 1 1
      frameworks/Java/play2-java/play2-java-jpa-hikaricp.dockerfile
  15. 30 0
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/app/startup/Startup.java
  16. 18 0
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/app/startup/StartupModule.java
  17. 9 6
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/conf/application.conf
  18. 1 0
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/conf/logback.xml
  19. 1 1
      frameworks/Java/play2-java/play2-java-netty.dockerfile
  20. 1 1
      frameworks/Java/play2-java/play2-java.dockerfile
  21. 26 0
      frameworks/Java/play2-java/play2-java/app/startup/Startup.java
  22. 18 0
      frameworks/Java/play2-java/play2-java/app/startup/StartupModule.java
  23. 8 4
      frameworks/Java/play2-java/play2-java/conf/application.conf
  24. 1 0
      frameworks/Java/play2-java/play2-java/conf/logback.xml
  25. 1 1
      frameworks/Scala/play2-scala/play2-scala-anorm-netty.dockerfile
  26. 1 1
      frameworks/Scala/play2-scala/play2-scala-anorm.dockerfile
  27. 25 0
      frameworks/Scala/play2-scala/play2-scala-anorm/app/startup/Startup.scala
  28. 10 0
      frameworks/Scala/play2-scala/play2-scala-anorm/app/startup/StartupModule.scala
  29. 9 6
      frameworks/Scala/play2-scala/play2-scala-anorm/conf/application.conf
  30. 29 0
      frameworks/Scala/play2-scala/play2-scala-anorm/conf/logback.xml
  31. 1 1
      frameworks/Scala/play2-scala/play2-scala-netty.dockerfile
  32. 1 1
      frameworks/Scala/play2-scala/play2-scala-reactivemongo-netty.dockerfile
  33. 1 1
      frameworks/Scala/play2-scala/play2-scala-reactivemongo.dockerfile
  34. 8 1
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/app/AppLoader.scala
  35. 21 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/app/startup/Startup.scala
  36. 4 6
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/application.conf
  37. 29 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/logback.xml
  38. 1 1
      frameworks/Scala/play2-scala/play2-scala-slick-netty.dockerfile
  39. 1 1
      frameworks/Scala/play2-scala/play2-scala-slick.dockerfile
  40. 23 0
      frameworks/Scala/play2-scala/play2-scala-slick/app/startup/Startup.scala
  41. 10 0
      frameworks/Scala/play2-scala/play2-scala-slick/app/startup/StartupModule.scala
  42. 9 6
      frameworks/Scala/play2-scala/play2-scala-slick/conf/application.conf
  43. 29 0
      frameworks/Scala/play2-scala/play2-scala-slick/conf/logback.xml
  44. 1 1
      frameworks/Scala/play2-scala/play2-scala.dockerfile
  45. 21 0
      frameworks/Scala/play2-scala/play2-scala/app/startup/Startup.scala
  46. 10 0
      frameworks/Scala/play2-scala/play2-scala/app/startup/StartupModule.scala
  47. 8 4
      frameworks/Scala/play2-scala/play2-scala/conf/application.conf
  48. 29 0
      frameworks/Scala/play2-scala/play2-scala/conf/logback.xml

+ 1 - 1
frameworks/Java/play2-java/play2-java-ebean-hikaricp-netty.dockerfile

@@ -5,4 +5,4 @@ COPY play2-java-ebean-hikaricp .
 RUN sed -i 's/.enablePlugins(PlayJava, PlayEbean, PlayNettyServer)/.enablePlugins(PlayJava, PlayEbean, PlayNettyServer).disablePlugins(PlayAkkaHttpServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-java-ebean-hikaricp", "-Dplay.server.provider=play.core.server.NettyServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-java-ebean-hikaricp -Dplay.server.provider=play.core.server.NettyServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 1 - 1
frameworks/Java/play2-java/play2-java-ebean-hikaricp.dockerfile

@@ -5,4 +5,4 @@ COPY play2-java-ebean-hikaricp .
 RUN sed -i 's/.enablePlugins(PlayJava, PlayEbean, PlayNettyServer)/.enablePlugins(PlayJava, PlayEbean).disablePlugins(PlayNettyServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-java-ebean-hikaricp", "-Dplay.server.provider=play.core.server.AkkaHttpServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-java-ebean-hikaricp -Dplay.server.provider=play.core.server.AkkaHttpServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 30 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/startup/Startup.java

@@ -0,0 +1,30 @@
+package startup;
+
+import com.typesafe.config.Config;
+import play.Logger;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class Startup {
+
+    private static final Logger.ALogger logger = Logger.of(Startup.class);
+
+    @Inject
+    public Startup(final Config config) {
+        logger.info("System properties");
+        logger.info("-----------------");
+        logger.info("physical_cpu_count: {}", System.getProperty("physical_cpu_count"));
+        logger.info("thread_count: {}", System.getProperty("thread_count"));
+        logger.info("db_pool_size: {}", System.getProperty("db_pool_size"));
+        logger.info("");
+        logger.info("Configuration");
+        logger.info("-------------");
+        logger.info("akka.actor.default-dispatcher.fork-join-executor.parallelism-max: {}", config.getInt("akka.actor.default-dispatcher.fork-join-executor.parallelism-max"));
+        logger.info("fixedConnectionPool: {}", config.getInt("fixedConnectionPool"));
+        logger.info("database.dispatcher.thread-pool-executor.fixed-pool-size: {}", config.getInt("database.dispatcher.thread-pool-executor.fixed-pool-size"));
+        logger.info("db.default.hikaricp.maximumPoolSize: {}", config.getInt("db.default.hikaricp.maximumPoolSize"));
+        logger.info("");
+    }
+}

+ 18 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/startup/StartupModule.java

@@ -0,0 +1,18 @@
+package startup;
+
+import com.typesafe.config.Config;
+import play.Environment;
+import play.inject.Binding;
+import play.inject.Module;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class StartupModule extends Module {
+
+    @Override
+    public List<Binding<?>> bindings(final Environment environment, final Config config) {
+        return Arrays.asList(bindClass(Startup.class).toSelf().eagerly());
+    }
+
+}

+ 9 - 6
frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/application.conf

@@ -13,6 +13,10 @@ play.i18n.langs = [ "en" ]
 # Disable default filters
 play.filters.enabled = [ ]
 
+play.modules {
+  enabled += "startup.StartupModule"
+}
+
 play.server.server-header = "Play2"
 
 play.server {
@@ -42,10 +46,10 @@ akka {
   actor {
     default-dispatcher {
       fork-join-executor {
-        # The TechEmpower benchmark environment uses 4x 10-Core E7-4850 CPUs in the application server
-        # That is 40 physical cores / 80 hyperthreaded cores
-        # https://www.techempower.com/benchmarks/#section=environment
-        parallelism-max = 40
+        # Information about the TechEmpower benchmark environment: https://www.techempower.com/benchmarks/#section=environment
+        # The environment variable physical_cpu_count does NOT include the hyperthreaded cores!
+        parallelism-max = 14
+        parallelism-max = ${?physical_cpu_count}
 
         task-peeking-mode="LIFO" # based on https://www.playframework.com/documentation/2.7.x/Migration24#Thread-pool-configuration
       }
@@ -62,10 +66,9 @@ akka {
 # Number of database connections
 # https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
 # db connections = ((physical_core_count * 2) + effective_spindle_count)
-# The TechEmpower benchmark environment uses 2 x 4-Core E5520 CPUs in the database server
-# That is 8 physical cores
 # https://www.techempower.com/benchmarks/#section=environment
 fixedConnectionPool = 17
+fixedConnectionPool = ${?db_pool_size}
 
 database.dispatcher {
     executor = "thread-pool-executor"

+ 1 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/logback.xml

@@ -20,6 +20,7 @@
   -->
   <logger name="play" level="INFO" />
   <logger name="application" level="INFO" />
+  <logger name="startup" level="INFO" />
 
   <root level="ERROR">
     <appender-ref ref="ASYNCSTDOUT" />

+ 1 - 1
frameworks/Java/play2-java/play2-java-jooq-hikaricp-netty.dockerfile

@@ -5,4 +5,4 @@ COPY play2-java-jooq-hikaricp .
 RUN sed -i 's/.enablePlugins(PlayJava, PlayNettyServer)/.enablePlugins(PlayJava, PlayNettyServer).disablePlugins(PlayAkkaHttpServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-java-jooq-hikaricp", "-Dplay.server.provider=play.core.server.NettyServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-java-jooq-hikaricp -Dplay.server.provider=play.core.server.NettyServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 1 - 1
frameworks/Java/play2-java/play2-java-jooq-hikaricp.dockerfile

@@ -5,4 +5,4 @@ COPY play2-java-jooq-hikaricp .
 RUN sed -i 's/.enablePlugins(PlayJava, PlayNettyServer)/.enablePlugins(PlayJava).disablePlugins(PlayNettyServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-java-jooq-hikaricp", "-Dplay.server.provider=play.core.server.AkkaHttpServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-java-jooq-hikaricp -Dplay.server.provider=play.core.server.AkkaHttpServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 30 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/startup/Startup.java

@@ -0,0 +1,30 @@
+package startup;
+
+import com.typesafe.config.Config;
+import play.Logger;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class Startup {
+
+    private static final Logger.ALogger logger = Logger.of(Startup.class);
+
+    @Inject
+    public Startup(final Config config) {
+        logger.info("System properties");
+        logger.info("-----------------");
+        logger.info("physical_cpu_count: {}", System.getProperty("physical_cpu_count"));
+        logger.info("thread_count: {}", System.getProperty("thread_count"));
+        logger.info("db_pool_size: {}", System.getProperty("db_pool_size"));
+        logger.info("");
+        logger.info("Configuration");
+        logger.info("-------------");
+        logger.info("akka.actor.default-dispatcher.fork-join-executor.parallelism-max: {}", config.getInt("akka.actor.default-dispatcher.fork-join-executor.parallelism-max"));
+        logger.info("fixedConnectionPool: {}", config.getInt("fixedConnectionPool"));
+        logger.info("database.dispatcher.thread-pool-executor.fixed-pool-size: {}", config.getInt("database.dispatcher.thread-pool-executor.fixed-pool-size"));
+        logger.info("db.default.hikaricp.maximumPoolSize: {}", config.getInt("db.default.hikaricp.maximumPoolSize"));
+        logger.info("");
+    }
+}

+ 18 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/startup/StartupModule.java

@@ -0,0 +1,18 @@
+package startup;
+
+import com.typesafe.config.Config;
+import play.Environment;
+import play.inject.Binding;
+import play.inject.Module;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class StartupModule extends Module {
+
+    @Override
+    public List<Binding<?>> bindings(final Environment environment, final Config config) {
+        return Arrays.asList(bindClass(Startup.class).toSelf().eagerly());
+    }
+
+}

+ 9 - 6
frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/application.conf

@@ -13,6 +13,10 @@ play.i18n.langs = [ "en" ]
 # Disable default filters
 play.filters.enabled = [ ]
 
+play.modules {
+  enabled += "startup.StartupModule"
+}
+
 play.server.server-header = "Play2"
 
 play.server {
@@ -42,10 +46,10 @@ akka {
   actor {
     default-dispatcher {
       fork-join-executor {
-        # The TechEmpower benchmark environment uses 4x 10-Core E7-4850 CPUs in the application server
-        # That is 40 physical cores / 80 hyperthreaded cores
-        # https://www.techempower.com/benchmarks/#section=environment
-        parallelism-max = 40
+        # Information about the TechEmpower benchmark environment: https://www.techempower.com/benchmarks/#section=environment
+        # The environment variable physical_cpu_count does NOT include the hyperthreaded cores!
+        parallelism-max = 14
+        parallelism-max = ${?physical_cpu_count}
 
         task-peeking-mode="LIFO" # based on https://www.playframework.com/documentation/2.7.x/Migration24#Thread-pool-configuration
       }
@@ -62,10 +66,9 @@ akka {
 # Number of database connections
 # https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
 # db connections = ((physical_core_count * 2) + effective_spindle_count)
-# The TechEmpower benchmark environment uses 2 x 4-Core E5520 CPUs in the database server
-# That is 8 physical cores
 # https://www.techempower.com/benchmarks/#section=environment
 fixedConnectionPool = 17
+fixedConnectionPool = ${?db_pool_size}
 
 database.dispatcher {
     executor = "thread-pool-executor"

+ 1 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/logback.xml

@@ -20,6 +20,7 @@
   -->
   <logger name="play" level="INFO" />
   <logger name="application" level="INFO" />
+  <logger name="startup" level="INFO" />
 
   <root level="ERROR">
     <appender-ref ref="ASYNCSTDOUT" />

+ 1 - 1
frameworks/Java/play2-java/play2-java-jpa-hikaricp-netty.dockerfile

@@ -5,4 +5,4 @@ COPY play2-java-jpa-hikaricp .
 RUN sed -i 's/.enablePlugins(PlayJava, PlayNettyServer)/.enablePlugins(PlayJava, PlayNettyServer).disablePlugins(PlayAkkaHttpServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-java-jpa-hikaricp", "-Dplay.server.provider=play.core.server.NettyServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-java-jpa-hikaricp -Dplay.server.provider=play.core.server.NettyServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 1 - 1
frameworks/Java/play2-java/play2-java-jpa-hikaricp.dockerfile

@@ -5,4 +5,4 @@ COPY play2-java-jpa-hikaricp .
 RUN sed -i 's/.enablePlugins(PlayJava, PlayNettyServer)/.enablePlugins(PlayJava).disablePlugins(PlayNettyServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-java-jpa-hikaricp", "-Dplay.server.provider=play.core.server.AkkaHttpServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-java-jpa-hikaricp -Dplay.server.provider=play.core.server.AkkaHttpServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 30 - 0
frameworks/Java/play2-java/play2-java-jpa-hikaricp/app/startup/Startup.java

@@ -0,0 +1,30 @@
+package startup;
+
+import com.typesafe.config.Config;
+import play.Logger;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class Startup {
+
+    private static final Logger.ALogger logger = Logger.of(Startup.class);
+
+    @Inject
+    public Startup(final Config config) {
+        logger.info("System properties");
+        logger.info("-----------------");
+        logger.info("physical_cpu_count: {}", System.getProperty("physical_cpu_count"));
+        logger.info("thread_count: {}", System.getProperty("thread_count"));
+        logger.info("db_pool_size: {}", System.getProperty("db_pool_size"));
+        logger.info("");
+        logger.info("Configuration");
+        logger.info("-------------");
+        logger.info("akka.actor.default-dispatcher.fork-join-executor.parallelism-max: {}", config.getInt("akka.actor.default-dispatcher.fork-join-executor.parallelism-max"));
+        logger.info("fixedConnectionPool: {}", config.getInt("fixedConnectionPool"));
+        logger.info("database.dispatcher.thread-pool-executor.fixed-pool-size: {}", config.getInt("database.dispatcher.thread-pool-executor.fixed-pool-size"));
+        logger.info("db.default.hikaricp.maximumPoolSize: {}", config.getInt("db.default.hikaricp.maximumPoolSize"));
+        logger.info("");
+    }
+}

+ 18 - 0
frameworks/Java/play2-java/play2-java-jpa-hikaricp/app/startup/StartupModule.java

@@ -0,0 +1,18 @@
+package startup;
+
+import com.typesafe.config.Config;
+import play.Environment;
+import play.inject.Binding;
+import play.inject.Module;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class StartupModule extends Module {
+
+    @Override
+    public List<Binding<?>> bindings(final Environment environment, final Config config) {
+        return Arrays.asList(bindClass(Startup.class).toSelf().eagerly());
+    }
+
+}

+ 9 - 6
frameworks/Java/play2-java/play2-java-jpa-hikaricp/conf/application.conf

@@ -13,6 +13,10 @@ play.i18n.langs = [ "en" ]
 # Disable default filters
 play.filters.enabled = [ ]
 
+play.modules {
+  enabled += "startup.StartupModule"
+}
+
 play.server.server-header = "Play2"
 
 play.server {
@@ -42,10 +46,10 @@ akka {
   actor {
     default-dispatcher {
       fork-join-executor {
-        # The TechEmpower benchmark environment uses 4x 10-Core E7-4850 CPUs in the application server
-        # That is 40 physical cores / 80 hyperthreaded cores
-        # https://www.techempower.com/benchmarks/#section=environment
-        parallelism-max = 40
+        # Information about the TechEmpower benchmark environment: https://www.techempower.com/benchmarks/#section=environment
+        # The environment variable physical_cpu_count does NOT include the hyperthreaded cores!
+        parallelism-max = 14
+        parallelism-max = ${?physical_cpu_count}
 
         task-peeking-mode="LIFO" # based on https://www.playframework.com/documentation/2.7.x/Migration24#Thread-pool-configuration
       }
@@ -62,10 +66,9 @@ akka {
 # Number of database connections
 # https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
 # db connections = ((physical_core_count * 2) + effective_spindle_count)
-# The TechEmpower benchmark environment uses 2 x 4-Core E5520 CPUs in the database server
-# That is 8 physical cores
 # https://www.techempower.com/benchmarks/#section=environment
 fixedConnectionPool = 17
+fixedConnectionPool = ${?db_pool_size}
 
 database.dispatcher {
     executor = "thread-pool-executor"

+ 1 - 0
frameworks/Java/play2-java/play2-java-jpa-hikaricp/conf/logback.xml

@@ -20,6 +20,7 @@
   -->
   <logger name="play" level="INFO" />
   <logger name="application" level="INFO" />
+  <logger name="startup" level="INFO" />
 
   <root level="ERROR">
     <appender-ref ref="ASYNCSTDOUT" />

+ 1 - 1
frameworks/Java/play2-java/play2-java-netty.dockerfile

@@ -5,4 +5,4 @@ COPY play2-java .
 RUN sed -i 's/.enablePlugins(PlayJava, PlayNettyServer)/.enablePlugins(PlayJava, PlayNettyServer).disablePlugins(PlayAkkaHttpServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-java", "-Dplay.server.provider=play.core.server.NettyServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-java -Dplay.server.provider=play.core.server.NettyServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}')

+ 1 - 1
frameworks/Java/play2-java/play2-java.dockerfile

@@ -5,4 +5,4 @@ COPY play2-java .
 RUN sed -i 's/.enablePlugins(PlayJava, PlayNettyServer)/.enablePlugins(PlayJava).disablePlugins(PlayNettyServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-java", "-Dplay.server.provider=play.core.server.AkkaHttpServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-java -Dplay.server.provider=play.core.server.AkkaHttpServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}')

+ 26 - 0
frameworks/Java/play2-java/play2-java/app/startup/Startup.java

@@ -0,0 +1,26 @@
+package startup;
+
+import com.typesafe.config.Config;
+import play.Logger;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class Startup {
+
+    private static final Logger.ALogger logger = Logger.of(Startup.class);
+
+    @Inject
+    public Startup(final Config config) {
+        logger.info("System properties");
+        logger.info("-----------------");
+        logger.info("physical_cpu_count: {}", System.getProperty("physical_cpu_count"));
+        logger.info("thread_count: {}", System.getProperty("thread_count"));
+        logger.info("");
+        logger.info("Configuration");
+        logger.info("-------------");
+        logger.info("akka.actor.default-dispatcher.fork-join-executor.parallelism-max: {}", config.getInt("akka.actor.default-dispatcher.fork-join-executor.parallelism-max"));
+        logger.info("");
+    }
+}

+ 18 - 0
frameworks/Java/play2-java/play2-java/app/startup/StartupModule.java

@@ -0,0 +1,18 @@
+package startup;
+
+import com.typesafe.config.Config;
+import play.Environment;
+import play.inject.Binding;
+import play.inject.Module;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class StartupModule extends Module {
+
+    @Override
+    public List<Binding<?>> bindings(final Environment environment, final Config config) {
+        return Arrays.asList(bindClass(Startup.class).toSelf().eagerly());
+    }
+
+}

+ 8 - 4
frameworks/Java/play2-java/play2-java/conf/application.conf

@@ -13,6 +13,10 @@ play.i18n.langs = [ "en" ]
 # Disable default filters
 play.filters.enabled = [ ]
 
+play.modules {
+  enabled += "startup.StartupModule"
+}
+
 play.server.server-header = "Play2"
 
 play.server {
@@ -42,10 +46,10 @@ akka {
   actor {
     default-dispatcher {
       fork-join-executor {
-        # The TechEmpower benchmark environment uses 4x 10-Core E7-4850 CPUs in the application server
-        # That is 40 physical cores / 80 hyperthreaded cores
-        # https://www.techempower.com/benchmarks/#section=environment
-        parallelism-max = 40
+        # Information about the TechEmpower benchmark environment: https://www.techempower.com/benchmarks/#section=environment
+        # The environment variable physical_cpu_count does NOT include the hyperthreaded cores!
+        parallelism-max = 14
+        parallelism-max = ${?physical_cpu_count}
 
         task-peeking-mode="LIFO" # based on https://www.playframework.com/documentation/2.7.x/Migration24#Thread-pool-configuration
       }

+ 1 - 0
frameworks/Java/play2-java/play2-java/conf/logback.xml

@@ -20,6 +20,7 @@
   -->
   <logger name="play" level="INFO" />
   <logger name="application" level="INFO" />
+  <logger name="startup" level="INFO" />
 
   <root level="ERROR">
     <appender-ref ref="ASYNCSTDOUT" />

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-anorm-netty.dockerfile

@@ -5,4 +5,4 @@ COPY play2-scala-anorm .
 RUN sed -i 's/.enablePlugins(PlayScala, PlayNettyServer)/.enablePlugins(PlayScala, PlayNettyServer).disablePlugins(PlayAkkaHttpServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-scala-anorm", "-Dplay.server.provider=play.core.server.NettyServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-scala-anorm -Dplay.server.provider=play.core.server.NettyServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-anorm.dockerfile

@@ -5,4 +5,4 @@ COPY play2-scala-anorm .
 RUN sed -i 's/.enablePlugins(PlayScala, PlayNettyServer)/.enablePlugins(PlayScala).disablePlugins(PlayNettyServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-scala-anorm", "-Dplay.server.provider=play.core.server.AkkaHttpServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-scala-anorm -Dplay.server.provider=play.core.server.AkkaHttpServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 25 - 0
frameworks/Scala/play2-scala/play2-scala-anorm/app/startup/Startup.scala

@@ -0,0 +1,25 @@
+package startup
+
+import com.typesafe.config.Config
+import javax.inject._
+import play.api.Logger
+
+@Singleton
+class Startup @Inject()(config: Config) {
+
+  private val logger = Logger(classOf[Startup])
+
+  logger.info("System properties")
+  logger.info("-----------------")
+  logger.info("physical_cpu_count: " + System.getProperty("physical_cpu_count"))
+  logger.info("thread_count: " + System.getProperty("thread_count"))
+  logger.info("db_pool_size: " + System.getProperty("db_pool_size"))
+  logger.info("")
+  logger.info("Configuration")
+  logger.info("-------------")
+  logger.info("akka.actor.default-dispatcher.fork-join-executor.parallelism-max: " + config.getInt("akka.actor.default-dispatcher.fork-join-executor.parallelism-max"))
+  logger.info("fixedConnectionPool: " + config.getInt("fixedConnectionPool"));
+  logger.info("database.dispatcher.thread-pool-executor.fixed-pool-size: " + config.getInt("database.dispatcher.thread-pool-executor.fixed-pool-size"));
+  logger.info("db.default.hikaricp.maximumPoolSize: " + config.getInt("db.default.hikaricp.maximumPoolSize"));
+
+}

+ 10 - 0
frameworks/Scala/play2-scala/play2-scala-anorm/app/startup/StartupModule.scala

@@ -0,0 +1,10 @@
+package startup
+
+import play.api._
+import play.api.inject._
+
+class StartupModule extends Module {
+  def bindings(environment: Environment, configuration: Configuration) = Seq(
+    bind[Startup].toSelf.eagerly
+  )
+}

+ 9 - 6
frameworks/Scala/play2-scala/play2-scala-anorm/conf/application.conf

@@ -13,6 +13,10 @@ play.i18n.langs = [ "en" ]
 # Disable default filters
 play.filters.enabled = [ ]
 
+play.modules {
+  enabled += "startup.StartupModule"
+}
+
 play.server.server-header = "Play2"
 
 play.server {
@@ -42,10 +46,10 @@ akka {
   actor {
     default-dispatcher {
       fork-join-executor {
-        # The TechEmpower benchmark environment uses 4x 10-Core E7-4850 CPUs in the application server
-        # That is 40 physical cores / 80 hyperthreaded cores
-        # https://www.techempower.com/benchmarks/#section=environment
-        parallelism-max = 40
+        # Information about the TechEmpower benchmark environment: https://www.techempower.com/benchmarks/#section=environment
+        # The environment variable physical_cpu_count does NOT include the hyperthreaded cores!
+        parallelism-max = 14
+        parallelism-max = ${?physical_cpu_count}
 
         task-peeking-mode="LIFO" # based on https://www.playframework.com/documentation/2.7.x/Migration24#Thread-pool-configuration
       }
@@ -62,10 +66,9 @@ akka {
 # Number of database connections
 # https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
 # db connections = ((physical_core_count * 2) + effective_spindle_count)
-# The TechEmpower benchmark environment uses 2 x 4-Core E5520 CPUs in the database server
-# That is 8 physical cores
 # https://www.techempower.com/benchmarks/#section=environment
 fixedConnectionPool = 17
+fixedConnectionPool = ${?db_pool_size}
 
 database.dispatcher {
     executor = "thread-pool-executor"

+ 29 - 0
frameworks/Scala/play2-scala/play2-scala-anorm/conf/logback.xml

@@ -0,0 +1,29 @@
+<configuration>
+    
+  <conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
+    </encoder>
+  </appender>
+
+  <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>500</queueSize>
+    <discardingThreshold>0</discardingThreshold>
+    <appender-ref ref="STDOUT" />
+  </appender>
+
+  <!--
+    The logger name is typically the Java/Scala package name.
+    This configures the log level to log at for a package and its children packages.
+  -->
+  <logger name="play" level="INFO" />
+  <logger name="application" level="INFO" />
+  <logger name="startup" level="INFO" />
+
+  <root level="ERROR">
+    <appender-ref ref="ASYNCSTDOUT" />
+  </root>
+
+</configuration>

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-netty.dockerfile

@@ -5,4 +5,4 @@ COPY play2-scala .
 RUN sed -i 's/.enablePlugins(PlayScala, PlayNettyServer)/.enablePlugins(PlayScala, PlayNettyServer).disablePlugins(PlayAkkaHttpServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-scala", "-Dplay.server.provider=play.core.server.NettyServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-scala -Dplay.server.provider=play.core.server.NettyServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}')

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-reactivemongo-netty.dockerfile

@@ -5,4 +5,4 @@ COPY play2-scala-reactivemongo .
 RUN sed -i 's/.enablePlugins(PlayScala, PlayNettyServer)/.enablePlugins(PlayScala, PlayNettyServer).disablePlugins(PlayAkkaHttpServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-scala-reactivemongo", "-Dplay.server.provider=play.core.server.NettyServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-scala-reactivemongo -Dplay.server.provider=play.core.server.NettyServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}')

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-reactivemongo.dockerfile

@@ -5,4 +5,4 @@ COPY play2-scala-reactivemongo .
 RUN sed -i 's/.enablePlugins(PlayScala, PlayNettyServer)/.enablePlugins(PlayScala).disablePlugins(PlayNettyServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-scala-reactivemongo", "-Dplay.server.provider=play.core.server.AkkaHttpServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-scala-reactivemongo -Dplay.server.provider=play.core.server.AkkaHttpServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}')

+ 8 - 1
frameworks/Scala/play2-scala/play2-scala-reactivemongo/app/AppLoader.scala

@@ -5,9 +5,16 @@ import ApplicationLoader.Context
 
 import com.softwaremill.macwire._
 import play.modules.reactivemongo.ReactiveMongoApiFromContext
+import startup.Startup
 
 class AppLoader extends ApplicationLoader {
-  def load(context: Context) = new AppComponents(context).application
+  def load(context: Context) = {
+    LoggerConfigurator(context.environment.classLoader).foreach {
+      _.configure(context.environment, context.initialConfiguration, Map.empty)
+    }
+    new Startup(context.initialConfiguration.underlying)
+    new AppComponents(context).application
+  }
 }
 
 class AppComponents(context: Context)

+ 21 - 0
frameworks/Scala/play2-scala/play2-scala-reactivemongo/app/startup/Startup.scala

@@ -0,0 +1,21 @@
+package startup
+
+import com.typesafe.config.Config
+import javax.inject._
+import play.api.Logger
+
+@Singleton
+class Startup @Inject()(config: Config) {
+
+  private val logger = Logger(classOf[Startup])
+
+  logger.info("System properties")
+  logger.info("-----------------")
+  logger.info("physical_cpu_count: " + System.getProperty("physical_cpu_count"))
+  logger.info("thread_count: " + System.getProperty("thread_count"))
+  logger.info("")
+  logger.info("Configuration")
+  logger.info("-------------")
+  logger.info("akka.actor.default-dispatcher.fork-join-executor.parallelism-max: " + config.getInt("akka.actor.default-dispatcher.fork-join-executor.parallelism-max"))
+
+}

+ 4 - 6
frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/application.conf

@@ -42,10 +42,10 @@ akka {
   actor {
     default-dispatcher {
       fork-join-executor {
-        # The TechEmpower benchmark environment uses 4x 10-Core E7-4850 CPUs in the application server
-        # That is 40 physical cores / 80 hyperthreaded cores
-        # https://www.techempower.com/benchmarks/#section=environment
-        parallelism-max = 40
+        # Information about the TechEmpower benchmark environment: https://www.techempower.com/benchmarks/#section=environment
+        # The environment variable physical_cpu_count does NOT include the hyperthreaded cores!
+        parallelism-max = 14
+        parallelism-max = ${?physical_cpu_count}
 
         task-peeking-mode="LIFO" # based on https://www.playframework.com/documentation/2.7.x/Migration24#Thread-pool-configuration
       }
@@ -61,8 +61,6 @@ akka {
 
 play.application.loader=AppLoader
 
-play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule"
-
 mongodb {
   servers = ["tfb-database:27017"]
   db = "hello_world"

+ 29 - 0
frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/logback.xml

@@ -0,0 +1,29 @@
+<configuration>
+    
+  <conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
+    </encoder>
+  </appender>
+
+  <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>500</queueSize>
+    <discardingThreshold>0</discardingThreshold>
+    <appender-ref ref="STDOUT" />
+  </appender>
+
+  <!--
+    The logger name is typically the Java/Scala package name.
+    This configures the log level to log at for a package and its children packages.
+  -->
+  <logger name="play" level="INFO" />
+  <logger name="application" level="INFO" />
+  <logger name="startup" level="INFO" />
+
+  <root level="ERROR">
+    <appender-ref ref="ASYNCSTDOUT" />
+  </root>
+
+</configuration>

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-slick-netty.dockerfile

@@ -5,4 +5,4 @@ COPY play2-scala-slick .
 RUN sed -i 's/.enablePlugins(PlayScala, PlayNettyServer)/.enablePlugins(PlayScala, PlayNettyServer).disablePlugins(PlayAkkaHttpServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-scala-slick", "-Dplay.server.provider=play.core.server.NettyServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-scala-slick -Dplay.server.provider=play.core.server.NettyServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-slick.dockerfile

@@ -5,4 +5,4 @@ COPY play2-scala-slick .
 RUN sed -i 's/.enablePlugins(PlayScala, PlayNettyServer)/.enablePlugins(PlayScala).disablePlugins(PlayNettyServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-scala-slick", "-Dplay.server.provider=play.core.server.AkkaHttpServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-scala-slick -Dplay.server.provider=play.core.server.AkkaHttpServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') -Ddb_pool_size=$(( $(( $(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') * 2 )) + 1 ))

+ 23 - 0
frameworks/Scala/play2-scala/play2-scala-slick/app/startup/Startup.scala

@@ -0,0 +1,23 @@
+package startup
+
+import com.typesafe.config.Config
+import javax.inject._
+import play.api.Logger
+
+@Singleton
+class Startup @Inject()(config: Config) {
+
+  private val logger = Logger(classOf[Startup])
+
+  logger.info("System properties")
+  logger.info("-----------------")
+  logger.info("physical_cpu_count: " + System.getProperty("physical_cpu_count"))
+  logger.info("thread_count: " + System.getProperty("thread_count"))
+  logger.info("db_pool_size: " + System.getProperty("db_pool_size"))
+  logger.info("")
+  logger.info("Configuration")
+  logger.info("-------------")
+  logger.info("akka.actor.default-dispatcher.fork-join-executor.parallelism-max: " + config.getInt("akka.actor.default-dispatcher.fork-join-executor.parallelism-max"))
+  logger.info("slick.dbs.default.db.numThreads: " + config.getInt("slick.dbs.default.db.numThreads"));
+
+}

+ 10 - 0
frameworks/Scala/play2-scala/play2-scala-slick/app/startup/StartupModule.scala

@@ -0,0 +1,10 @@
+package startup
+
+import play.api._
+import play.api.inject._
+
+class StartupModule extends Module {
+  def bindings(environment: Environment, configuration: Configuration) = Seq(
+    bind[Startup].toSelf.eagerly
+  )
+}

+ 9 - 6
frameworks/Scala/play2-scala/play2-scala-slick/conf/application.conf

@@ -13,6 +13,10 @@ play.i18n.langs = [ "en" ]
 # Disable default filters
 play.filters.enabled = [ ]
 
+play.modules {
+  enabled += "startup.StartupModule"
+}
+
 play.server.server-header = "Play2"
 
 play.server {
@@ -42,10 +46,10 @@ akka {
   actor {
     default-dispatcher {
       fork-join-executor {
-        # The TechEmpower benchmark environment uses 4x 10-Core E7-4850 CPUs in the application server
-        # That is 40 physical cores / 80 hyperthreaded cores
-        # https://www.techempower.com/benchmarks/#section=environment
-        parallelism-max = 40
+        # Information about the TechEmpower benchmark environment: https://www.techempower.com/benchmarks/#section=environment
+        # The environment variable physical_cpu_count does NOT include the hyperthreaded cores!
+        parallelism-max = 14
+        parallelism-max = ${?physical_cpu_count}
 
         task-peeking-mode="LIFO" # based on https://www.playframework.com/documentation/2.7.x/Migration24#Thread-pool-configuration
       }
@@ -73,10 +77,9 @@ slick.dbs.default {
     # Number of threads
     # https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
     # db connections = ((physical_core_count * 2) + effective_spindle_count)
-    # The TechEmpower benchmark environment uses 2 x 4-Core E5520 CPUs in the database server
-    # That is 8 physical cores
     # https://www.techempower.com/benchmarks/#section=environment
     numThreads=17
+    numThreads=${?db_pool_size}
 
     queueSize=2000
 

+ 29 - 0
frameworks/Scala/play2-scala/play2-scala-slick/conf/logback.xml

@@ -0,0 +1,29 @@
+<configuration>
+    
+  <conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
+    </encoder>
+  </appender>
+
+  <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>500</queueSize>
+    <discardingThreshold>0</discardingThreshold>
+    <appender-ref ref="STDOUT" />
+  </appender>
+
+  <!--
+    The logger name is typically the Java/Scala package name.
+    This configures the log level to log at for a package and its children packages.
+  -->
+  <logger name="play" level="INFO" />
+  <logger name="application" level="INFO" />
+  <logger name="startup" level="INFO" />
+
+  <root level="ERROR">
+    <appender-ref ref="ASYNCSTDOUT" />
+  </root>
+
+</configuration>

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala.dockerfile

@@ -5,4 +5,4 @@ COPY play2-scala .
 RUN sed -i 's/.enablePlugins(PlayScala, PlayNettyServer)/.enablePlugins(PlayScala).disablePlugins(PlayNettyServer)/g' build.sbt
 
 RUN sbt stage
-CMD ["target/universal/stage/bin/play2-scala", "-Dplay.server.provider=play.core.server.AkkaHttpServerProvider", "-J-server", "-J-Xms1g", "-J-Xmx1g", "-J-XX:NewSize=512m", "-J-XX:+UseG1GC", "-J-XX:MaxGCPauseMillis=30", "-J-XX:-UseBiasedLocking", "-J-XX:+AlwaysPreTouch"]
+CMD target/universal/stage/bin/play2-scala -Dplay.server.provider=play.core.server.AkkaHttpServerProvider -J-server -J-Xms1g -J-Xmx1g -J-XX:NewSize=512m -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=30 -J-XX:-UseBiasedLocking -J-XX:+AlwaysPreTouch -Dthread_count=$(nproc) -Dphysical_cpu_count=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}')

+ 21 - 0
frameworks/Scala/play2-scala/play2-scala/app/startup/Startup.scala

@@ -0,0 +1,21 @@
+package startup
+
+import com.typesafe.config.Config
+import javax.inject._
+import play.api.Logger
+
+@Singleton
+class Startup @Inject()(config: Config) {
+
+  private val logger = Logger(classOf[Startup])
+
+  logger.info("System properties")
+  logger.info("-----------------")
+  logger.info("physical_cpu_count: " + System.getProperty("physical_cpu_count"))
+  logger.info("thread_count: " + System.getProperty("thread_count"))
+  logger.info("")
+  logger.info("Configuration")
+  logger.info("-------------")
+  logger.info("akka.actor.default-dispatcher.fork-join-executor.parallelism-max: " + config.getInt("akka.actor.default-dispatcher.fork-join-executor.parallelism-max"))
+
+}

+ 10 - 0
frameworks/Scala/play2-scala/play2-scala/app/startup/StartupModule.scala

@@ -0,0 +1,10 @@
+package startup
+
+import play.api._
+import play.api.inject._
+
+class StartupModule extends Module {
+  def bindings(environment: Environment, configuration: Configuration) = Seq(
+    bind[Startup].toSelf.eagerly
+  )
+}

+ 8 - 4
frameworks/Scala/play2-scala/play2-scala/conf/application.conf

@@ -13,6 +13,10 @@ play.i18n.langs = [ "en" ]
 # Disable default filters
 play.filters.enabled = [ ]
 
+play.modules {
+  enabled += "startup.StartupModule"
+}
+
 play.server.server-header = "Play2"
 
 play.server {
@@ -42,10 +46,10 @@ akka {
   actor {
     default-dispatcher {
       fork-join-executor {
-        # The TechEmpower benchmark environment uses 4x 10-Core E7-4850 CPUs in the application server
-        # That is 40 physical cores / 80 hyperthreaded cores
-        # https://www.techempower.com/benchmarks/#section=environment
-        parallelism-max = 40
+        # Information about the TechEmpower benchmark environment: https://www.techempower.com/benchmarks/#section=environment
+        # The environment variable physical_cpu_count does NOT include the hyperthreaded cores!
+        parallelism-max = 14
+        parallelism-max = ${?physical_cpu_count}
 
         task-peeking-mode="LIFO" # based on https://www.playframework.com/documentation/2.7.x/Migration24#Thread-pool-configuration
       }

+ 29 - 0
frameworks/Scala/play2-scala/play2-scala/conf/logback.xml

@@ -0,0 +1,29 @@
+<configuration>
+    
+  <conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
+    </encoder>
+  </appender>
+
+  <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>500</queueSize>
+    <discardingThreshold>0</discardingThreshold>
+    <appender-ref ref="STDOUT" />
+  </appender>
+
+  <!--
+    The logger name is typically the Java/Scala package name.
+    This configures the log level to log at for a package and its children packages.
+  -->
+  <logger name="play" level="INFO" />
+  <logger name="application" level="INFO" />
+  <logger name="startup" level="INFO" />
+
+  <root level="ERROR">
+    <appender-ref ref="ASYNCSTDOUT" />
+  </root>
+
+</configuration>