Skip to content

Commit 03c1c5c

Browse files
authored
[Ktor] Latest Ktor, serializer, html dsl versions (#9128)
* latest Ktor, serializer, html dsl versions jvm runtime is now 17 Update README.md modernized all ktor tests to jvm 17 and latest ktor small pgclient memory optimizations big cleanup, removed pg-reactive-client, since it's evolution is already being tested a small memory optimization * fixed obsolete config * cleaned up legacy test
1 parent 527c38d commit 03c1c5c

File tree

22 files changed

+156
-235
lines changed

22 files changed

+156
-235
lines changed

frameworks/Kotlin/ktor/benchmark_config.json

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,29 +94,6 @@
9494
"notes": "",
9595
"versus": "netty"
9696
},
97-
"reactivepg": {
98-
"json_url": "/json",
99-
"plaintext_url": "/plaintext",
100-
"db_url": "/db",
101-
"query_url": "/query/?queries=",
102-
"fortune_url": "/fortunes",
103-
"update_url": "/updates?queries=",
104-
"port": 8080,
105-
"approach": "Realistic",
106-
"classification": "Fullstack",
107-
"database": "Postgres",
108-
"framework": "Ktor",
109-
"language": "Kotlin",
110-
"flavor": "None",
111-
"orm": "Raw",
112-
"platform": "None",
113-
"webserver": "None",
114-
"os": "Linux",
115-
"database_os": "Linux",
116-
"display_name": "Ktor-reactivepg",
117-
"notes": "",
118-
"versus": "netty"
119-
},
12097
"pgclient": {
12198
"plaintext_url": "/plaintext",
12299
"json_url": "/json",

frameworks/Kotlin/ktor/config.toml

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,6 @@ platform = "None"
3535
webserver = "None"
3636
versus = "netty"
3737

38-
[reactivepg]
39-
urls.plaintext = "/plaintext"
40-
urls.json = "/json"
41-
urls.db = "/db"
42-
urls.query = "/query/?queries="
43-
urls.update = "/updates?queries="
44-
urls.fortune = "/fortunes"
45-
approach = "Realistic"
46-
classification = "Fullstack"
47-
database = "Postgres"
48-
database_os = "Linux"
49-
os = "Linux"
50-
orm = "Raw"
51-
platform = "None"
52-
webserver = "None"
53-
versus = "netty"
54-
5538
[cio]
5639
urls.plaintext = "/plaintext"
5740
urls.json = "/json"

frameworks/Kotlin/ktor/ktor-asyncdb/build.gradle

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
plugins {
2+
application
3+
kotlin("jvm") version "1.9.22"
4+
kotlin("plugin.serialization") version "2.0.0"
5+
id("com.github.johnrengelman.shadow") version "8.1.0"
6+
}
7+
8+
group = "org.jetbrains.ktor"
9+
version = "1.0-SNAPSHOT"
10+
11+
repositories {
12+
mavenCentral()
13+
}
14+
15+
application {
16+
mainClass.set("MainKt")
17+
}
18+
19+
val ktor_version = "2.3.12"
20+
val kotlinx_serialization_version = "1.6.3"
21+
val vertx_pg_client = "4.5.8"
22+
23+
dependencies {
24+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_serialization_version")
25+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
26+
implementation("io.ktor:ktor-server-netty:$ktor_version")
27+
implementation("io.ktor:ktor-server-default-headers:$ktor_version")
28+
implementation("io.ktor:ktor-server-html-builder:$ktor_version")
29+
implementation("com.github.jasync-sql:jasync-postgresql:2.2.0")
30+
}
31+
32+
tasks.shadowJar {
33+
archiveBaseName.set("bench")
34+
archiveClassifier.set("")
35+
archiveVersion.set("")
36+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
kotlin.code.style=official
22

3-
kotlin_version=1.3.31
4-
ktor_version=1.2.0
3+
kotlin_version=1.9.22
4+
ktor_version=2.3.12

frameworks/Kotlin/ktor/ktor-asyncdb/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip

frameworks/Kotlin/ktor/ktor-asyncdb/src/main/kotlin/main.kt

Lines changed: 41 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
11
import com.github.jasync.sql.db.ConnectionPoolConfiguration
2+
import com.github.jasync.sql.db.QueryResult
23
import com.github.jasync.sql.db.SuspendingConnection
34
import com.github.jasync.sql.db.asSuspending
45
import com.github.jasync.sql.db.postgresql.PostgreSQLConnectionBuilder
5-
import io.ktor.application.call
6-
import io.ktor.application.install
7-
import io.ktor.features.DefaultHeaders
8-
import io.ktor.html.Placeholder
9-
import io.ktor.html.Template
10-
import io.ktor.html.insert
11-
import io.ktor.html.respondHtmlTemplate
126
import io.ktor.http.ContentType
13-
import io.ktor.response.respondText
14-
import io.ktor.routing.get
15-
import io.ktor.routing.routing
7+
import io.ktor.server.application.*
168
import io.ktor.server.engine.embeddedServer
9+
import io.ktor.server.html.*
1710
import io.ktor.server.netty.Netty
18-
import io.reactiverse.kotlin.pgclient.getConnectionAwait
19-
import io.reactiverse.kotlin.pgclient.preparedBatchAwait
20-
import io.reactiverse.kotlin.pgclient.preparedQueryAwait
21-
import io.reactiverse.pgclient.*
11+
import io.ktor.server.plugins.defaultheaders.*
12+
import io.ktor.server.response.*
13+
import io.ktor.server.routing.*
14+
import kotlinx.coroutines.*
2215
import kotlinx.html.*
2316
import kotlinx.serialization.Serializable
24-
import kotlinx.serialization.json.JSON
25-
import kotlinx.serialization.list
17+
import kotlinx.serialization.encodeToString
18+
import kotlinx.serialization.json.Json
2619
import java.lang.IllegalArgumentException
2720
import kotlin.random.Random
2821
import kotlin.random.nextInt
@@ -44,73 +37,48 @@ interface Repository {
4437
}
4538

4639
class JasyncRepository() : Repository {
47-
private val dbConfig: ConnectionPoolConfiguration
48-
private val db: SuspendingConnection
49-
50-
init {
51-
dbConfig = ConnectionPoolConfiguration(
52-
"tfb-database",
53-
database = "hello_world",
54-
username = "benchmarkdbuser",
55-
password = "benchmarkdbpass",
56-
maxActiveConnections = 64
57-
)
58-
db = PostgreSQLConnectionBuilder.createConnectionPool(dbConfig).asSuspending
40+
companion object {
41+
const val WORLD_QUERY = "select id, randomNumber from world where id = ?"
42+
const val FORTUNES_QUERY = "select id, message from fortune"
43+
const val UPDATE_QUERY = "update world set randomNumber = ? where id = ?"
5944
}
6045

46+
private val dbConfig: ConnectionPoolConfiguration = ConnectionPoolConfiguration(
47+
"tfb-database",
48+
database = "hello_world",
49+
username = "benchmarkdbuser",
50+
password = "benchmarkdbpass",
51+
maxActiveConnections = 64
52+
)
53+
private val db: SuspendingConnection = PostgreSQLConnectionBuilder.createConnectionPool(dbConfig).asSuspending
54+
6155
override suspend fun getWorld(): World {
6256
val worldId = rand.nextInt(1, 10000)
63-
val result = db.sendPreparedStatement("select id, randomNumber from world where id = ?", listOf(worldId))
57+
val result = db.sendPreparedStatement(WORLD_QUERY, listOf(worldId))
6458
val row = result.rows.first()
6559
return World(row.getInt(0)!!, row.getInt(1)!!)
6660
}
6761

6862
override suspend fun getFortunes(): List<Fortune> {
69-
val results = db.sendPreparedStatement("select id, message from fortune")
63+
val results = db.sendPreparedStatement(FORTUNES_QUERY)
7064
return results.rows.map { Fortune(it.getInt(0)!!, it.getString(1)!!) }
7165
}
7266

7367
override suspend fun updateWorlds(worlds: List<World>) {
74-
worlds.forEach { world ->
75-
db.sendPreparedStatement(
76-
"update world set randomNumber = ? where id = ?",
77-
listOf(world.randomNumber, world.id)
78-
)
79-
}
80-
}
81-
}
68+
coroutineScope {
69+
val jobs = ArrayList<Deferred<QueryResult>>(worlds.size)
70+
worlds.forEach { world ->
71+
val deferred = async(Dispatchers.IO) {
72+
db.sendPreparedStatement(
73+
UPDATE_QUERY,
74+
listOf(world.randomNumber, world.id)
75+
)
76+
}
77+
jobs.add(deferred)
78+
}
8279

83-
class ReactivePGRepository : Repository {
84-
private val db: PgPool
85-
86-
init {
87-
val poolOptions = PgPoolOptions()
88-
poolOptions.apply {
89-
host = "tfb-database"
90-
database = "hello_world"
91-
user = "benchmarkdbuser"
92-
password = "benchmarkdbpass"
93-
maxSize = 64
94-
cachePreparedStatements = true
80+
jobs.awaitAll()
9581
}
96-
db = PgClient.pool(poolOptions)
97-
}
98-
99-
override suspend fun getFortunes(): List<Fortune> {
100-
val results = db.preparedQueryAwait("select id, message from fortune")
101-
return results.map { Fortune(it.getInteger(0), it.getString(1)) }
102-
}
103-
104-
override suspend fun getWorld(): World {
105-
val worldId = rand.nextInt(1, 10000)
106-
val result = db.preparedQueryAwait("select id, randomNumber from world where id = $1", Tuple.of(worldId))
107-
val row = result.first()
108-
return World(row.getInteger(0), row.getInteger(1)!!)
109-
}
110-
111-
override suspend fun updateWorlds(worlds: List<World>) {
112-
val batch = worlds.map { Tuple.of(it.id, it.randomNumber) }
113-
db.preparedBatchAwait("update world set randomNumber = $1 where id = $2", batch)
11482
}
11583
}
11684

@@ -132,7 +100,7 @@ class MainTemplate : Template<HTML> {
132100
}
133101
}
134102

135-
class FortuneTemplate(val fortunes: List<Fortune>, val main: MainTemplate = MainTemplate()) : Template<HTML> {
103+
class FortuneTemplate(private val fortunes: List<Fortune>, private val main: MainTemplate = MainTemplate()) : Template<HTML> {
136104
override fun HTML.apply() {
137105
insert(main) {
138106
content {
@@ -156,13 +124,9 @@ class FortuneTemplate(val fortunes: List<Fortune>, val main: MainTemplate = Main
156124
fun main(args: Array<String>) {
157125
val db = when(args.firstOrNull()) {
158126
"jasync-sql" -> JasyncRepository()
159-
"reactive-pg" -> ReactivePGRepository()
160127
else -> throw IllegalArgumentException("Must specify a postgres client")
161128
}
162129

163-
val messageSerializer = Message.serializer()
164-
val worldSerializer = World.serializer()
165-
166130
val server = embeddedServer(Netty, 8080, configure = {
167131
shareWorkGroup = true
168132
}) {
@@ -174,19 +138,19 @@ fun main(args: Array<String>) {
174138

175139
get("/json") {
176140
call.respondText(
177-
JSON.stringify(messageSerializer, Message("Hello, World!")),
141+
Json.encodeToString(Message("Hello, World!")),
178142
ContentType.Application.Json
179143
)
180144
}
181145

182146
get("/db") {
183-
call.respondText(JSON.stringify(worldSerializer, db.getWorld()), ContentType.Application.Json)
147+
call.respondText(Json.encodeToString(db.getWorld()), ContentType.Application.Json)
184148
}
185149

186150
get("/query/") {
187151
val queries = call.parameters["queries"]?.toBoxedInt(1..500) ?: 1
188152
val worlds = (1..queries).map { db.getWorld() }
189-
call.respondText(JSON.stringify(worldSerializer.list, worlds), ContentType.Application.Json)
153+
call.respondText(Json.encodeToString(worlds), ContentType.Application.Json)
190154
}
191155

192156
get("/fortunes") {
@@ -204,7 +168,7 @@ fun main(args: Array<String>) {
204168

205169
db.updateWorlds(newWorlds)
206170

207-
call.respondText(JSON.stringify(worldSerializer.list, newWorlds), ContentType.Application.Json)
171+
call.respondText(Json.encodeToString(newWorlds), ContentType.Application.Json)
208172
}
209173
}
210174
}

frameworks/Kotlin/ktor/ktor-cio.dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
FROM maven:3.6.1-jdk-11-slim as maven
1+
FROM maven:3.9.7-amazoncorretto-17-debian as maven
22
WORKDIR /ktor
33
COPY ktor/pom.xml pom.xml
44
COPY ktor/src src
55
RUN mvn clean package -q
66

7-
FROM openjdk:11.0.3-jdk-stretch
7+
FROM amazoncorretto:17.0.11-al2023-headless
88
WORKDIR /ktor
99
COPY --from=maven /ktor/target/tech-empower-framework-benchmark-1.0-SNAPSHOT-cio-bundle.jar app.jar
1010

frameworks/Kotlin/ktor/ktor-exposed-dao.dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM gradle:8.0.2-jdk11
1+
FROM gradle:jdk17
22

33
WORKDIR /ktor-exposed
44
COPY ktor-exposed/settings.gradle.kts settings.gradle.kts

frameworks/Kotlin/ktor/ktor-exposed-dsl.dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM gradle:8.0.2-jdk11
1+
FROM gradle:jdk17
22

33
WORKDIR /ktor-exposed
44
COPY ktor-exposed/settings.gradle.kts settings.gradle.kts

0 commit comments

Comments
 (0)