Browse Source

vertx-web-kotlin-dsljson updates (#9192)

* minor performance improvements and warning suppression

* vertx-web-kotlin-dsljson updates

* formatting

* update postgres socket connection config
Andrew McCloskey 1 year ago
parent
commit
ee5d2b2b85

+ 6 - 6
frameworks/Kotlin/vertx-web-kotlin-dsljson/configuration/scripts/server.sh

@@ -1,16 +1,17 @@
 #!/bin/bash
 
-NUM_PROCESSORS=$((`grep --count ^processor /proc/cpuinfo`))
-
 JVM_OPTS="-server \
   -Xms2G \
   -Xmx2G \
+  -XX:+AlwaysPreTouch \
   -XX:+UseParallelGC \
+  -XX:+PreserveFramePointer \
+  -XX:+EnableDynamicAgentLoading \
   -XX:InitialCodeCacheSize=512m \
   -XX:ReservedCodeCacheSize=512m \
   -XX:MaxInlineLevel=20 \
-  -XX:+AlwaysPreTouch \
   -XX:+UseNUMA \
+  -Djava.lang.Integer.IntegerCache.high=10000 \
   -Dvertx.disableMetrics=true \
   -Dvertx.disableH2c=true \
   -Dvertx.disableWebsockets=true \
@@ -19,6 +20,7 @@ JVM_OPTS="-server \
   -Dvertx.disableContextTimings=true \
   -Dvertx.disableTCCL=true \
   -Dvertx.disableHttpHeadersValidation=true \
+  -Dvertx.eventLoopPoolSize=$((`grep --count ^processor /proc/cpuinfo`)) \
   -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \
   -Dio.netty.buffer.checkBounds=false \
   -Dio.netty.buffer.checkAccessible=false \
@@ -26,8 +28,6 @@ JVM_OPTS="-server \
 
 JAR_PATH="./build/libs/vertx-web-kotlin-dsljson-benchmark-1.0.0-SNAPSHOT-fat.jar"
 
-VERTX_ARGS="-instances 1"
-
 cleanup() {
     echo "Caught SIGINT signal. Stopping the Java program..."
     if [ ! -z "$JAVA_PID" ]; then
@@ -39,7 +39,7 @@ cleanup() {
 
 trap cleanup SIGINT
 
-java $JVM_OPTS -jar $JAR_PATH $VERTX_ARGS &
+java $JVM_OPTS -jar $JAR_PATH &
 JAVA_PID=$!
 
 echo "Server PID: $JAVA_PID"

+ 4 - 4
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/App.kt

@@ -3,7 +3,6 @@ package com.example.starter
 import com.example.starter.utils.PeriodicDateResolver
 import com.example.starter.utils.block
 import io.vertx.core.Vertx
-import io.vertx.core.impl.cpu.CpuCoreSensor
 import io.vertx.kotlin.core.deploymentOptionsOf
 import io.vertx.kotlin.core.vertxOptionsOf
 import kotlin.time.Duration.Companion.seconds
@@ -14,11 +13,12 @@ object App : Logging {
 
     @JvmStatic
     fun main(args: Array<out String?>?) {
-        val numCores = CpuCoreSensor.availableProcessors()
+        val eventLoopPoolSize = System.getProperty("vertx.eventLoopPoolSize")?.toInt()
+            ?: Runtime.getRuntime().availableProcessors()
 
         val vertx = Vertx.vertx(
             vertxOptionsOf(
-                eventLoopPoolSize = numCores,
+                eventLoopPoolSize = eventLoopPoolSize,
                 preferNativeTransport = true,
             )
         )
@@ -41,7 +41,7 @@ object App : Logging {
         vertx.deployVerticle(
             { if (hasDb) PostgresVerticle() else BasicVerticle() },
             deploymentOptionsOf(
-                instances = numCores,
+                instances = eventLoopPoolSize,
             )
         )
 

+ 4 - 11
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/PostgresVerticle.kt

@@ -5,10 +5,8 @@ import com.example.starter.db.WorldRepository
 import com.example.starter.handlers.FortuneHandler
 import com.example.starter.handlers.WorldHandler
 import com.example.starter.io.JsonResource
-import com.example.starter.utils.array
 import com.example.starter.utils.isConnectionReset
 import io.vertx.core.AbstractVerticle
-import io.vertx.core.Future
 import io.vertx.core.Promise
 import io.vertx.core.http.HttpServerOptions
 import io.vertx.ext.web.Router
@@ -18,15 +16,10 @@ import org.apache.logging.log4j.kotlin.Logging
 
 class PostgresVerticle : AbstractVerticle() {
     override fun start(startPromise: Promise<Void>) {
-        Future.all(
-            PgConnection.connect(vertx, PG_CONNECT_OPTIONS),
-            PgConnection.connect(vertx, PG_CONNECT_OPTIONS),
-        )
-            .onSuccess { cf ->
-                val pool = cf.array<PgConnection>()
-
-                val fortuneHandler = FortuneHandler(FortuneRepository(pool))
-                val worldHandler = WorldHandler(WorldRepository(pool))
+        PgConnection.connect(vertx, PG_CONNECT_OPTIONS)
+            .onSuccess { conn ->
+                val fortuneHandler = FortuneHandler(FortuneRepository(conn))
+                val worldHandler = WorldHandler(WorldRepository(conn))
 
                 val router = Router.router(vertx)
 

+ 1 - 1
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/db/AbstractRepository.kt

@@ -3,5 +3,5 @@ package com.example.starter.db
 import io.vertx.pgclient.PgConnection
 
 abstract class AbstractRepository<T>(
-    protected val pool: Array<PgConnection>
+    protected val conn: PgConnection
 )

+ 2 - 2
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/db/FortuneRepository.kt

@@ -7,8 +7,8 @@ import io.vertx.core.Future
 import io.vertx.pgclient.PgConnection
 import io.vertx.sqlclient.Row
 
-class FortuneRepository(pool: Array<PgConnection>) : AbstractRepository<Fortune>(pool) {
-    private val selectFortuneQuery = this.pool[0].preparedQuery(SELECT_FORTUNE_SQL)
+class FortuneRepository(conn: PgConnection) : AbstractRepository<Fortune>(conn) {
+    private val selectFortuneQuery = this.conn.preparedQuery(SELECT_FORTUNE_SQL)
 
     fun selectFortunes(): Future<Array<Fortune>> = selectFortuneQuery
         .execute()

+ 5 - 5
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/db/WorldRepository.kt

@@ -13,10 +13,10 @@ import io.vertx.sqlclient.impl.SqlClientInternal
 import java.util.concurrent.ThreadLocalRandom
 import java.util.concurrent.atomic.AtomicInteger
 
-@Suppress("NOTHING_TO_INLINE")
-class WorldRepository(pool: Array<PgConnection>) : AbstractRepository<World>(pool) {
-    private val selectWorldQuery = this.pool[0].preparedQuery(SELECT_WORLD_SQL)
-    private val updateWorldQueries = generateQueries(this.pool[1])
+@Suppress("NOTHING_TO_INLINE", "UNCHECKED_CAST")
+class WorldRepository(conn: PgConnection) : AbstractRepository<World>(conn) {
+    private val selectWorldQuery = this.conn.preparedQuery(SELECT_WORLD_SQL)
+    private val updateWorldQueries = generateQueries(this.conn)
 
     fun selectRandomWorld(): Future<World> = selectWorldQuery
         .execute(Tuple.of(randomWorld()))
@@ -26,7 +26,7 @@ class WorldRepository(pool: Array<PgConnection>) : AbstractRepository<World>(poo
         val promise = Promise.promise<Array<World>>()
         val arr = arrayOfNulls<World>(numWorlds)
         val count = AtomicInteger(0)
-        (this.pool[0] as SqlClientInternal).group { c ->
+        (this.conn as SqlClientInternal).group { c ->
             repeat(numWorlds) {
                 c.preparedQuery(SELECT_WORLD_SQL).execute(Tuple.of(randomWorld())) { ar ->
                     val index = count.getAndIncrement()

+ 1 - 1
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/utils/JsonExtensions.kt

@@ -16,4 +16,4 @@ inline fun <T> T.serialize(initialSizeHint: Int = 0): Buffer {
     val output = BufferOutputStream(initialSizeHint)
     DSL_JSON.serialize(this, output)
     return output
-}
+}

+ 5 - 2
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/utils/PeriodicDateResolver.kt

@@ -1,16 +1,19 @@
 package com.example.starter.utils
 
 import io.vertx.core.Vertx
+import io.vertx.core.http.HttpHeaders
 import java.time.ZonedDateTime
 import java.time.format.DateTimeFormatter
 
 object PeriodicDateResolver {
-    var current: String = next()
+    var current: CharSequence = next()
 
     fun init(vertx: Vertx) {
         vertx.setPeriodic(1000L) { current = next() }
     }
 
     @Suppress("NOTHING_TO_INLINE")
-    private inline fun next(): String = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now())
+    private inline fun next(): CharSequence = HttpHeaders.createOptimized(
+        DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now())
+    )
 }

+ 2 - 1
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/utils/RowSetExtensions.kt

@@ -5,10 +5,11 @@ import io.vertx.sqlclient.RowSet
 
 // This extension relies on the assumption the mapper never returns null, as it is defined. Otherwise,
 // we prevent the overhead from having to do another iteration over the loop for a `filterNotNull` check.
+@Suppress("UNCHECKED_CAST")
 inline fun <reified U> RowSet<Row>.mapToArray(mapper: (Row) -> U): Array<U> {
     val arr = arrayOfNulls<U>(this.size())
     val iterator = this.iterator()
     var index = 0
     while (iterator.hasNext()) arr[index++] = mapper(iterator.next())
     return arr as Array<U>
-}
+}

+ 8 - 4
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/kotlin/com/example/starter/utils/ThrowableExtensions.kt

@@ -6,7 +6,11 @@ import java.net.SocketException
 
 const val CONNECTION_RESET_MESSAGE = "Connection reset"
 
-fun Throwable.isConnectionReset(): Boolean {
-    return (this is NativeIoException && this.expectedErr() == Errors.ERRNO_ECONNRESET_NEGATIVE)
-        || (this is SocketException && this.message == CONNECTION_RESET_MESSAGE)
-}
+@Suppress("NOTHING_TO_INLINE")
+inline fun Throwable.isConnectionReset(): Boolean {
+    return when {
+        this is NativeIoException && this.expectedErr() == Errors.ERRNO_ECONNRESET_NEGATIVE -> true
+        this is SocketException && this.message == CONNECTION_RESET_MESSAGE -> true
+        else -> false
+    }
+}

+ 1 - 4
frameworks/Kotlin/vertx-web-kotlin-dsljson/src/main/resources/pg-connect-options.json

@@ -5,10 +5,7 @@
   "port": 5432,
   "database": "hello_world",
   "cachePreparedStatements": true,
-  "preparedStatementCacheMaxSize": 512,
-  "preparedStatementCacheSqlLimit": 2048,
-  "tcpKeepAlive": true,
-  "tcpFastOpen": true,
+  "preparedStatementCacheMaxSize": 1024,
   "pipeliningLimit": 100000,
   "receiveBufferSize": 262144,
   "sendBufferSize": 262144

+ 3 - 1
frameworks/Kotlin/vertx-web-kotlin-dsljson/vertx-web-kotlin-dsljson-postgresql.dockerfile

@@ -17,10 +17,11 @@ CMD java \
     -Xmx2G \
     -XX:+AlwaysPreTouch \
     -XX:+UseParallelGC \
-	-XX:InitialCodeCacheSize=512m \
+    -XX:InitialCodeCacheSize=512m \
     -XX:ReservedCodeCacheSize=512m \
     -XX:MaxInlineLevel=20 \
     -XX:+UseNUMA \
+    -Djava.lang.Integer.IntegerCache.high=10000 \
     -Dvertx.disableMetrics=true \
     -Dvertx.disableH2c=true \
     -Dvertx.disableWebsockets=true \
@@ -29,6 +30,7 @@ CMD java \
     -Dvertx.disableContextTimings=true \
     -Dvertx.disableTCCL=true \
     -Dvertx.disableHttpHeadersValidation=true \
+    -Dvertx.eventLoopPoolSize=$((`grep --count ^processor /proc/cpuinfo`)) \
     -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \
     -Dio.netty.buffer.checkBounds=false \
     -Dio.netty.buffer.checkAccessible=false \

+ 3 - 1
frameworks/Kotlin/vertx-web-kotlin-dsljson/vertx-web-kotlin-dsljson.dockerfile

@@ -17,10 +17,11 @@ CMD java \
     -Xmx2G \
     -XX:+AlwaysPreTouch \
     -XX:+UseParallelGC \
-	-XX:InitialCodeCacheSize=512m \
+    -XX:InitialCodeCacheSize=512m \
     -XX:ReservedCodeCacheSize=512m \
     -XX:MaxInlineLevel=20 \
     -XX:+UseNUMA \
+    -Djava.lang.Integer.IntegerCache.high=10000 \
     -Dvertx.disableMetrics=true \
     -Dvertx.disableH2c=true \
     -Dvertx.disableWebsockets=true \
@@ -29,6 +30,7 @@ CMD java \
     -Dvertx.disableContextTimings=true \
     -Dvertx.disableTCCL=true \
     -Dvertx.disableHttpHeadersValidation=true \
+    -Dvertx.eventLoopPoolSize=$((`grep --count ^processor /proc/cpuinfo`)) \
     -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \
     -Dio.netty.buffer.checkBounds=false \
     -Dio.netty.buffer.checkAccessible=false \