|
@@ -1,5 +1,8 @@
|
|
package benchmark
|
|
package benchmark
|
|
|
|
|
|
|
|
+import benchmark.data.Fortune
|
|
|
|
+import benchmark.data.TFBRepository
|
|
|
|
+import com.fizzed.rocker.runtime.StringBuilderOutput
|
|
import dev.pellet.logging.pelletLogger
|
|
import dev.pellet.logging.pelletLogger
|
|
import dev.pellet.server.PelletBuilder.httpRouter
|
|
import dev.pellet.server.PelletBuilder.httpRouter
|
|
import dev.pellet.server.PelletBuilder.pelletServer
|
|
import dev.pellet.server.PelletBuilder.pelletServer
|
|
@@ -13,15 +16,23 @@ import java.time.Instant
|
|
import java.time.ZoneId
|
|
import java.time.ZoneId
|
|
import java.time.format.DateTimeFormatter
|
|
import java.time.format.DateTimeFormatter
|
|
import java.util.Locale
|
|
import java.util.Locale
|
|
|
|
+import java.util.concurrent.ThreadLocalRandom
|
|
|
|
|
|
object Benchmark
|
|
object Benchmark
|
|
|
|
|
|
val logger = pelletLogger<Benchmark>()
|
|
val logger = pelletLogger<Benchmark>()
|
|
|
|
+val jsonEncoder = Json {
|
|
|
|
+ prettyPrint = false
|
|
|
|
+}
|
|
|
|
|
|
fun main() = runBlocking {
|
|
fun main() = runBlocking {
|
|
val sharedRouter = httpRouter {
|
|
val sharedRouter = httpRouter {
|
|
get("/plaintext", ::handlePlain)
|
|
get("/plaintext", ::handlePlain)
|
|
get("/json", ::handleJson)
|
|
get("/json", ::handleJson)
|
|
|
|
+ get("/db", ::handleDb)
|
|
|
|
+ get("/query", ::handleQuery)
|
|
|
|
+ get("/updates", ::handleUpdates)
|
|
|
|
+ get("/fortunes", ::handleFortunes)
|
|
}
|
|
}
|
|
val pellet = pelletServer {
|
|
val pellet = pelletServer {
|
|
logRequests = false
|
|
logRequests = false
|
|
@@ -62,8 +73,80 @@ private suspend fun handleJson(
|
|
val responseBody = ResponseBody(message = "Hello, World!")
|
|
val responseBody = ResponseBody(message = "Hello, World!")
|
|
return HTTPRouteResponse.Builder()
|
|
return HTTPRouteResponse.Builder()
|
|
.statusCode(200)
|
|
.statusCode(200)
|
|
- .jsonEntity(Json, responseBody)
|
|
|
|
|
|
+ .jsonEntity(jsonEncoder, responseBody)
|
|
|
|
+ .header("Server", "pellet")
|
|
|
|
+ .header("Date", dateFormatter.format(Instant.now()))
|
|
|
|
+ .build()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+private val repository = TFBRepository()
|
|
|
|
+
|
|
|
|
+private suspend fun handleDb(
|
|
|
|
+ context: PelletHTTPRouteContext
|
|
|
|
+): HTTPRouteResponse {
|
|
|
|
+ val result = repository.fetchWorld()
|
|
|
|
+ return HTTPRouteResponse.Builder()
|
|
|
|
+ .statusCode(200)
|
|
|
|
+ .jsonEntity(jsonEncoder, result)
|
|
|
|
+ .header("Server", "pellet")
|
|
|
|
+ .header("Date", dateFormatter.format(Instant.now()))
|
|
|
|
+ .build()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+private suspend fun handleQuery(
|
|
|
|
+ context: PelletHTTPRouteContext
|
|
|
|
+): HTTPRouteResponse {
|
|
|
|
+ val rawQueries = context.firstQueryParameter("queries").getOrNull()
|
|
|
|
+ val queries = (rawQueries?.toIntOrNull() ?: 1).coerceIn(1, 500)
|
|
|
|
+ val worlds = (1 .. queries)
|
|
|
|
+ .map {
|
|
|
|
+ repository.fetchWorld()
|
|
|
|
+ }
|
|
|
|
+ return HTTPRouteResponse.Builder()
|
|
|
|
+ .statusCode(200)
|
|
|
|
+ .jsonEntity(jsonEncoder, worlds)
|
|
|
|
+ .header("Server", "pellet")
|
|
|
|
+ .header("Date", dateFormatter.format(Instant.now()))
|
|
|
|
+ .build()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+private suspend fun handleUpdates(
|
|
|
|
+ context: PelletHTTPRouteContext
|
|
|
|
+): HTTPRouteResponse {
|
|
|
|
+ val rawQueries = context.firstQueryParameter("queries").getOrNull()
|
|
|
|
+ val queries = (rawQueries?.toIntOrNull() ?: 1).coerceIn(1, 500)
|
|
|
|
+ val worlds = (1 .. queries)
|
|
|
|
+ .map {
|
|
|
|
+ repository.fetchWorld()
|
|
|
|
+ }
|
|
|
|
+ val newWorlds = worlds.map {
|
|
|
|
+ it.copy(
|
|
|
|
+ randomNumber = ThreadLocalRandom.current().nextInt(1, 10001)
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ repository.updateWorlds(newWorlds)
|
|
|
|
+ return HTTPRouteResponse.Builder()
|
|
|
|
+ .statusCode(200)
|
|
|
|
+ .jsonEntity(jsonEncoder, newWorlds)
|
|
.header("Server", "pellet")
|
|
.header("Server", "pellet")
|
|
.header("Date", dateFormatter.format(Instant.now()))
|
|
.header("Date", dateFormatter.format(Instant.now()))
|
|
.build()
|
|
.build()
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+private suspend fun handleFortunes(
|
|
|
|
+ context: PelletHTTPRouteContext
|
|
|
|
+): HTTPRouteResponse {
|
|
|
|
+ val newFortune = Fortune(0, "Additional fortune added at request time.")
|
|
|
|
+ val fortunes = repository.fetchFortunes().toMutableList()
|
|
|
|
+ fortunes.add(newFortune)
|
|
|
|
+ fortunes.sortBy { it.message }
|
|
|
|
+ val template = views.fortunes.template(fortunes)
|
|
|
|
+ .render(StringBuilderOutput.FACTORY)
|
|
|
|
+ .toString()
|
|
|
|
+ return HTTPRouteResponse.Builder()
|
|
|
|
+ .statusCode(200)
|
|
|
|
+ .entity(template, "text/html; charset=utf-8")
|
|
|
|
+ .header("Server", "pellet")
|
|
|
|
+ .header("Date", dateFormatter.format(Instant.now()))
|
|
|
|
+ .build()
|
|
|
|
+}
|