Browse Source

Update Hexagon version to fix bug (#2280)

Juanjo Aguililla 9 years ago
parent
commit
096e800d26

+ 2 - 3
frameworks/Kotlin/hexagon/gradle.properties

@@ -3,10 +3,9 @@ version=1.0.0
 group=co.there4.hexagon
 description=Hexagon web framework's benchmark
 
-wrapperGradleVersion=2.14.1
+wrapperGradleVersion=3.0
 gradleScripts=https://raw.githubusercontent.com/jaguililla/hexagon/master/gradle
-org.gradle.daemon=true
 
 dokkaVersion=0.9.+
 kotlinVersion=1.0.3
-hexagonVersion=0.8.2
+hexagonVersion=0.9.2

+ 39 - 51
frameworks/Kotlin/hexagon/src/main/kotlin/co/there4/hexagon/Benchmark.kt

@@ -1,78 +1,68 @@
 package co.there4.hexagon
 
-import co.there4.hexagon.settings.SettingsManager.setting
-import java.util.concurrent.ThreadLocalRandom
-
+import co.there4.hexagon.repository.*
 import co.there4.hexagon.serialization.serialize
-import co.there4.hexagon.repository.MongoIdRepository
-import co.there4.hexagon.repository.mongoCollection
-import co.there4.hexagon.repository.mongoDatabase
+import co.there4.hexagon.settings.SettingsManager.setting
 import co.there4.hexagon.web.*
-import co.there4.hexagon.web.jetty.JettyServer
 
 import java.lang.System.getenv
 import java.net.InetAddress.getByName as address
 import java.time.LocalDateTime.now
-import kotlin.reflect.KClass
+import java.util.concurrent.ThreadLocalRandom
 
-internal data class Message (val message: String = "Hello, World!")
-internal data class Fortune (val _id: Int, val message: String)
-internal data class World (val id: Int, val randomNumber: Int)
+import kotlin.reflect.KProperty1
 
-private val BIND = setting<String>("bindAddress") ?: "localhost"
-private val BIND_ADDRESS = address(BIND)
-private val BIND_PORT = setting<Int>("bindPort") ?: 9090
+internal data class Message(val message: String = "Hello, World!")
+internal data class Fortune(val _id: Int, val message: String)
+internal data class World(val _id: Int, val id: Int, val randomNumber: Int)
 
 private val DB_ROWS = 10000
 private val CONTENT_TYPE_JSON = "application/json"
 private val QUERIES_PARAM = "queries"
 
+private val DB_HOST = getenv("DBHOST") ?: "localhost"
 private val DB = setting<String>("database") ?: "hello_world"
 private val WORLD: String = setting<String>("worldCollection") ?: "world"
 private val FORTUNE: String = setting<String>("fortuneCollection") ?: "fortune"
 
-private val DB_HOST = getenv("DBHOST") ?: "localhost"
-private val DB_PORT = 27017
-
-private val database = mongoDatabase("mongodb://$DB_HOST:$DB_PORT/$DB")
+private val database = mongoDatabase("mongodb://$DB_HOST/$DB")
+private val worldRepository = repository(WORLD, World::_id)
+private val fortuneRepository = repository(FORTUNE, Fortune::_id)
 
-private val worldRepository = repository(World::class, WORLD, { it.id })
-private val fortuneRepository = repository(Fortune::class, FORTUNE, { it._id })
+private inline fun <reified T : Any> repository(name: String, key: KProperty1<T, Int>) =
+    MongoIdRepository(T::class, mongoCollection(name, database), key)
 
-private fun <T : Any> repository(type: KClass<T>, name: String, keySupplier: (T) -> Int) =
-    MongoIdRepository(type, mongoCollection(name, database), keySupplier, Int::class, "_id")
-
-private fun rnd () = ThreadLocalRandom.current ().nextInt (DB_ROWS) + 1
+private fun rnd() = ThreadLocalRandom.current().nextInt(DB_ROWS) + 1
 
 private fun Exchange.hasQueryCount() = request[QUERIES_PARAM] == null
 
-private fun Exchange.getDb () {
-    val worlds = (1..getQueries()).map { worldRepository.find(rnd ()) }
+private fun Exchange.getDb() {
+    val worlds = (1..getQueries()).map { worldRepository.find(rnd()) }.filterNotNull()
 
     response.contentType = CONTENT_TYPE_JSON
-    ok (if (hasQueryCount()) worlds[0].serialize() else worlds.serialize())
+    ok(if (hasQueryCount()) worlds[0].serialize() else worlds.serialize())
 }
 
-private fun Exchange.getFortunes () {
-    val fortune = Fortune (0, "Additional fortune added at request time.")
-    val fortunes = fortuneRepository.findObjects ().toList() + fortune
+private fun Exchange.getFortunes() {
+    val fortune = Fortune(0, "Additional fortune added at request time.")
+    val fortunes = fortuneRepository.findObjects().toList() + fortune
 
-    response.contentType = "text/html; charset=utf-8"
-    template ("fortunes.html", mapOf ("fortunes" to fortunes.sortedBy { it.message }))
+    template("fortunes.html", mapOf("fortunes" to fortunes.sortedBy { it.message }))
 }
 
-private fun Exchange.getUpdates () {
-    val worlds =  (1..getQueries()).map {
-        val newWorld = World (rnd (), rnd())
-        worldRepository.replaceObject (newWorld)
+private fun Exchange.getUpdates() {
+    val worlds = (1..getQueries()).map {
+        val id = rnd()
+        val newWorld = World(id, id, rnd())
+        worldRepository.replaceObject(newWorld)
         newWorld
     }
 
     response.contentType = CONTENT_TYPE_JSON
-    ok (if (hasQueryCount()) worlds[0].serialize() else worlds.serialize())
+    ok(if (hasQueryCount()) worlds[0].serialize() else worlds.serialize())
 }
 
-private fun Exchange.getQueries () =
+private fun Exchange.getQueries() =
     try {
         val queries = request[QUERIES_PARAM]?.toInt() ?: 1
         when {
@@ -85,31 +75,29 @@ private fun Exchange.getQueries () =
         1
     }
 
-private fun Exchange.getPlaintext () {
+private fun Exchange.getPlaintext() {
     response.contentType = "text/plain"
     ok("Hello, World!")
 }
 
-private fun Exchange.getJson () {
+private fun Exchange.getJson() {
     response.contentType = CONTENT_TYPE_JSON
-    ok(Message ().serialize())
+    ok(Message().serialize())
 }
 
 fun main(args: Array<String>) {
-    server = JettyServer (bindAddress = BIND_ADDRESS, bindPort = BIND_PORT)
-
     before {
         response.addHeader("Server", "Servlet/3.1")
         response.addHeader("Transfer-Encoding", "chunked")
-        response.addHeader("Date", httpDate (now()))
+        response.addHeader("Date", httpDate(now()))
     }
 
-    get ("/json") { getJson() }
-    get ("/db") { getDb() }
-    get ("/query") { getDb() }
-    get ("/fortune") { getFortunes() }
-    get ("/update") { getUpdates() }
-    get ("/plaintext") { getPlaintext() }
+    get("/json") { getJson() }
+    get("/db") { getDb() }
+    get("/query") { getDb() }
+    get("/fortune") { getFortunes() }
+    get("/update") { getUpdates() }
+    get("/plaintext") { getPlaintext() }
 
-    run ()
+    run()
 }

+ 13 - 12
frameworks/Kotlin/hexagon/src/test/kotlin/co/there4/hexagon/BenchmarkTest.kt

@@ -5,19 +5,18 @@ import co.there4.hexagon.web.Client
 import org.asynchttpclient.Response
 import org.testng.annotations.BeforeClass
 import org.testng.annotations.Test
-import java.net.URL
 
 internal const val THREADS = 4
-internal const val TIMES = 16
+internal const val TIMES = 4
 
 @Test (threadPoolSize = THREADS, invocationCount = TIMES)
 class BenchmarkTest {
-    private val client = Client(URL("http://localhost:9090"))
+    private val client = Client("http://localhost:9090")
 
     @BeforeClass fun warmup() {
         main(arrayOf())
 
-        val warmupRounds = if (THREADS > 1) 5 else 0
+        val warmupRounds = if (THREADS > 1) 2 else 0
         (1 ..warmupRounds).forEach {
             json ()
             plaintext ()
@@ -48,7 +47,7 @@ class BenchmarkTest {
         val content = response.responseBody
 
         checkResponse (response, "application/json")
-        assert ("Hello, World!" == content.parse(Map::class)["message"])
+        assert ("Hello, World!" == content.parse(Message::class).message)
     }
 
     fun plaintext () {
@@ -61,11 +60,12 @@ class BenchmarkTest {
 
     fun no_query_parameter () {
         val response = client.get ("/db")
-        val content = response.responseBody
+        val body = response.responseBody
 
         checkResponse (response, "application/json")
-        val resultsMap = content.parse(Map::class)
-        assert (resultsMap.containsKey ("id") && resultsMap.containsKey ("randomNumber"))
+        val bodyMap = body.parse(Map::class)
+        assert(bodyMap.containsKey (World::_id.name))
+        assert(bodyMap.containsKey (World::randomNumber.name))
     }
 
     fun fortunes () {
@@ -82,11 +82,12 @@ class BenchmarkTest {
 
     fun no_updates_parameter () {
         val response = client.get ("/update")
-        val content = response.responseBody
+        val body = response.responseBody
 
         checkResponse (response, "application/json")
-        val resultsMap = content.parse(Map::class)
-        assert (resultsMap.containsKey ("id") && resultsMap.containsKey ("randomNumber"))
+        val bodyMap = body.parse(Map::class)
+        assert(bodyMap.containsKey (World::_id.name))
+        assert(bodyMap.containsKey (World::randomNumber.name))
     }
 
     fun empty_query_parameter () = checkDbRequest ("/query?queries", 1)
@@ -127,7 +128,7 @@ class BenchmarkTest {
 
         (1..size).forEach {
             val r = resultsList[it - 1] as Map<*, *>
-            assert (r.containsKey ("id") && r.containsKey ("randomNumber"))
+            assert (r.containsKey (World::_id.name) && r.containsKey (World::randomNumber.name))
         }
     }
 }