@@ -32,6 +32,14 @@ import org.jetbrains.ktor.benchmarks.models.World
3232import reactor.core.publisher.Flux
3333import reactor.core.publisher.Mono
3434import kotlin.random.Random
35+ import java.time.Duration
36+
37+ private val json = Json {
38+ prettyPrint = false
39+ isLenient = true
40+ ignoreUnknownKeys = true
41+ coerceInputValues = true
42+ }
3543
3644fun Application.main () {
3745 val config = ApplicationConfig (" application.conf" )
@@ -40,22 +48,23 @@ fun Application.main() {
4048 install(DefaultHeaders )
4149
4250 val helloWorldContent = TextContent (" Hello, World!" , ContentType .Text .Plain )
51+ val helloWorldMsg = Message (" Hello, world!" )
4352
4453 routing {
4554 get(" /plaintext" ) {
4655 call.respond(helloWorldContent)
4756 }
4857
4958 get(" /json" ) {
50- call.respondText(Json .encodeToString(Message ( " Hello, world! " ) ), ContentType .Application .Json )
59+ call.respondText(json .encodeToString(helloWorldMsg ), ContentType .Application .Json )
5160 }
5261
5362 get(" /db" ) {
5463 val random = Random .Default
5564 val request = getWorld(dbConnFactory, random)
5665 val result = request.awaitFirstOrNull()
5766
58- call.respondText(Json .encodeToString(result), ContentType .Application .Json )
67+ call.respondText(json .encodeToString(result), ContentType .Application .Json )
5968 }
6069
6170 fun selectWorlds (queries : Int , random : Random ): Flow <World > = flow {
@@ -74,7 +83,7 @@ fun Application.main() {
7483 }
7584 }
7685
77- call.respondText(Json .encodeToString(result), ContentType .Application .Json )
86+ call.respondText(json .encodeToString(result), ContentType .Application .Json )
7887 }
7988
8089 get(" /fortunes" ) {
@@ -135,21 +144,28 @@ fun Application.main() {
135144 }
136145 }
137146
138- call.respondText(Json .encodeToString(worldsUpdated), ContentType .Application .Json )
147+ call.respondText(json .encodeToString(worldsUpdated), ContentType .Application .Json )
139148 }
140149 }
141150}
142151
143152private fun getWorld (
144153 dbConnFactory : ConnectionFactory , random : Random
145154): Mono <World > = Mono .usingWhen(dbConnFactory.create(), { connection ->
146- Mono .from(connection.createStatement(WORLD_QUERY ).bind(0 , random.nextInt(DB_ROWS ) + 1 ).execute()).flatMap { r ->
147- Mono .from(r.map { row, _ ->
148- World (
149- row.get(0 , Int ::class .java)!! , row.get(1 , Int ::class .java)!!
150- )
151- })
152- }
155+ Mono .from(connection.createStatement(WORLD_QUERY )
156+ .bind(" $1" , random.nextInt(DB_ROWS ) + 1 )
157+ .execute())
158+ .flatMap { r ->
159+ Mono .from(r.map { row, _ ->
160+ val id = row.get(0 , Int ::class .java)
161+ val randomNumber = row.get(1 , Int ::class .java)
162+ if (id != null && randomNumber != null ) {
163+ World (id, randomNumber)
164+ } else {
165+ throw IllegalStateException (" Database returned null values for required fields" )
166+ }
167+ })
168+ }
153169}, Connection ::close)
154170
155171private fun configurePostgresR2DBC (config : ApplicationConfig ): ConnectionFactory {
@@ -170,6 +186,9 @@ private fun configurePostgresR2DBC(config: ApplicationConfig): ConnectionFactory
170186 val cp = ConnectionPoolConfiguration .builder(cf)
171187 .initialSize(config.property(" db.initPoolSize" ).getString().toInt())
172188 .maxSize(config.property(" db.maxPoolSize" ).getString().toInt())
189+ .maxIdleTime(Duration .ofSeconds(30 ))
190+ .maxAcquireTime(Duration .ofSeconds(5 ))
191+ .validationQuery(" SELECT 1" )
173192 .build()
174193
175194 return ConnectionPool (cp)
0 commit comments