Skip to content

Commit 11a2473

Browse files
committed
Merge branch 'kotlin-vertx-benchmarks-revamp-kotlinx-serialization-json-io' into kotlin-vertx-benchmarks-revamp
Use `encodeToSink` in "kotlinx-serialization-json-io" with a custom-implemented `VertxBufferRawSink` in JSON serialization
2 parents 770dfc0 + c00f23c commit 11a2473

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
lines changed

frameworks/Kotlin/vertx-web-kotlinx/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ The tests were run with:
2727
* [Vert.x Reactive PostgreSQL Client](https://vertx.io/docs/vertx-pg-client/java/)
2828
* [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines)
2929
* [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization)
30+
* [kotlinx-io](https://github.com/Kotlin/kotlinx-io)
3031
* [kotlinx.html](https://github.com/Kotlin/kotlinx.html)
3132

3233
## Test URLs

frameworks/Kotlin/vertx-web-kotlinx/build.gradle.kts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ repositories {
1414
}
1515

1616
val vertxVersion = "4.5.10"
17+
val kotlinxSerializationVersion = "1.7.3"
1718
dependencies {
1819
implementation(platform("io.vertx:vertx-stack-depchain:$vertxVersion"))
1920
implementation("io.vertx:vertx-web")
@@ -26,7 +27,11 @@ dependencies {
2627
runtimeOnly("io.netty.incubator:netty-incubator-transport-native-io_uring:0.0.25.Final:linux-x86_64")
2728

2829
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
29-
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
30+
31+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxSerializationVersion")
32+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-io:$kotlinxSerializationVersion")
33+
implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.5.4")
34+
3035
implementation("org.jetbrains.kotlinx:kotlinx-html:0.11.0")
3136
//implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0") // the latest version is 0.6.1
3237
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import io.vertx.core.streams.WriteStream
2+
import io.vertx.kotlin.coroutines.coAwait
3+
import kotlinx.coroutines.runBlocking
4+
import kotlinx.io.RawSink
5+
import kotlinx.io.readByteArray
6+
import io.vertx.core.buffer.Buffer as VertxBuffer
7+
import kotlinx.io.Buffer as KotlinxIoBuffer
8+
9+
@Suppress("NOTHING_TO_INLINE")
10+
private inline fun Long.toIntOrThrow(): Int {
11+
require(this in Int.MIN_VALUE.toLong()..Int.MAX_VALUE.toLong())
12+
return toInt()
13+
}
14+
15+
@JvmInline
16+
value class VertxBufferWriteStreamRawSink(val writeStream: WriteStream<VertxBuffer>) : RawSink {
17+
override fun write(source: KotlinxIoBuffer, byteCount: Long) {
18+
runBlocking {
19+
// `source` is temporarily converted to a byte array because wrapping it as a Vert.x `Buffer` is too complicated to implement.
20+
writeStream.write(VertxBuffer.buffer(source.readByteArray(byteCount.toIntOrThrow()))).coAwait()
21+
}
22+
}
23+
24+
override fun flush() {}
25+
26+
override fun close() {
27+
writeStream.end()
28+
}
29+
}
30+
31+
// not used currently
32+
fun WriteStream<VertxBuffer>.toRawSink(): RawSink =
33+
VertxBufferWriteStreamRawSink(this)
34+
35+
36+
@JvmInline
37+
value class VertxBufferRawSink(val vertxBuffer: VertxBuffer) : RawSink {
38+
override fun write(source: KotlinxIoBuffer, byteCount: Long) {
39+
// same problem as above
40+
vertxBuffer.appendBytes(source.readByteArray(byteCount.toIntOrThrow()))
41+
}
42+
43+
override fun flush() {}
44+
45+
override fun close() {}
46+
}
47+
48+
fun VertxBuffer.toRawSink(): RawSink =
49+
VertxBufferRawSink(this)

frameworks/Kotlin/vertx-web-kotlinx/src/main/kotlin/MainVerticle.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import io.netty.channel.unix.Errors.NativeIoException
2+
import io.vertx.core.buffer.Buffer
23
import io.vertx.core.http.HttpHeaders
34
import io.vertx.core.http.HttpServer
45
import io.vertx.core.http.HttpServerRequest
@@ -19,9 +20,12 @@ import kotlinx.coroutines.Dispatchers
1920
import kotlinx.coroutines.launch
2021
import kotlinx.html.*
2122
import kotlinx.html.stream.appendHTML
23+
import kotlinx.io.buffered
24+
import kotlinx.serialization.ExperimentalSerializationApi
2225
import kotlinx.serialization.Serializable
2326
import kotlinx.serialization.SerializationStrategy
2427
import kotlinx.serialization.json.Json
28+
import kotlinx.serialization.json.io.encodeToSink
2529
import java.time.ZonedDateTime
2630
import java.time.format.DateTimeFormatter
2731

@@ -120,7 +124,28 @@ class MainVerticle(val hasDb: Boolean) : CoroutineVerticle() {
120124
checkedCoroutineHandlerUnconfined {
121125
it.response().run {
122126
putJsonResponseHeader()
127+
128+
/*
129+
// approach 1
123130
end(Json.encodeToString(serializer, requestHandler(it)))/*.coAwait()*/
131+
*/
132+
133+
/*
134+
// approach 2
135+
// java.lang.IllegalStateException: You must set the Content-Length header to be the total size of the message body BEFORE sending any data if you are not using HTTP chunked encoding.
136+
toRawSink().buffered().use { bufferedSink ->
137+
@OptIn(ExperimentalSerializationApi::class)
138+
Json.encodeToSink(serializer, requestHandler(it), bufferedSink)
139+
}
140+
*/
141+
142+
// approach 3
143+
end(Buffer.buffer().apply {
144+
toRawSink().buffered().use { bufferedSink ->
145+
@OptIn(ExperimentalSerializationApi::class)
146+
Json.encodeToSink(serializer, requestHandler(it), bufferedSink)
147+
}
148+
})
124149
}
125150
}
126151

0 commit comments

Comments
 (0)