Browse Source

Add async-db test, update deps (#4827)

* Update clojure/reitit test

Add reactive SQL test for Clojure/Reitit.
Update dependencies
Fix reflection warning
Set worker thread pool to 256

* Fix reactive build

* Update porsas to latest, containing postgresql lib

* Add exception handling, no charset for plaintext

* Update README
Tommi Reiman 6 years ago
parent
commit
09a5fc8c1a

+ 11 - 9
frameworks/Clojure/reitit/README.md

@@ -1,22 +1,24 @@
 # Reitit Benchmarking Test
 
-This is the [Reitit](https://github.com/metosin/reitit) portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+This is the [Reitit](https://github.com/metosin/reitit) portion of a [benchmarking test suite](../) comparing a variety of web development platforms, both witb blocking JDBC via [HikariCP](https://github.com/tomekw/hikari-cp) and [The Reactive SQL Client](https://github.com/eclipse-vertx/vertx-sql-client).
 
-### JSON Encoding Test
+### Source
 
-* [JSON test source](hello/src/hello/handler.clj)
+* [`handler.clj`](hello/src/hello/handler.clj)
 
 ## Infrastructure Software Versions
 
 The dependencies are documented in [project.clj](hello/project.clj),
 but the main ones are:
 
-* [Clojure 1.9.0](http://clojure.org/)
-* [ikitommi/immutant-web "3.0.0-alpha1"](https://github.com/ikitommi/immutant) - a performant fork of [Immutant]((http://immutant.org/))
-* [metosin/jsonista "0.2.0"](https://github.com/metosin/jsonista)
-* [metosin/reitit "0.1.1-20180425.095607-7"](https://github.com/metosin/reitit)
+* [org.clojure/clojure](http://clojure.org/) - latest Clojure version
+* [ikitommi/immutant-web](https://github.com/ikitommi/immutant) - a performant fork of [Immutant]((http://immutant.org/))
+* [metosin/jsonista](https://github.com/metosin/jsonista) - fast JSON marchalling for Clojure
+* [metosin/reitit](https://github.com/metosin/reitit) - fast routing lib for Clojure/Script
+* [metosin/porsas](https://github.com/metosin/porsas) - fast database access for Clojure
 
 ## Test URLs
-### JSON Encoding Test
 
-http://localhost:8080/json
+* http://localhost:8080/json
+* http://localhost:8080/plaintext
+* http://localhost:8080/db

+ 43 - 21
frameworks/Clojure/reitit/benchmark_config.json

@@ -1,25 +1,47 @@
 {
   "framework": "reitit",
-  "tests": [{
-    "default": {
-      "json_url": "/json",
-      "plaintext_url": "/plaintext",
-      "db_url": "/db",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Micro",
-      "database": "Postgres",
-      "framework": "reitit",
-      "language": "Clojure",
-      "flavor": "None",
-      "orm": "Raw",
-      "platform": "Undertow",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "reitit",
-      "notes": "",
-      "versus": "Undertow"
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "db_url": "/db",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "Postgres",
+        "framework": "reitit",
+        "language": "Clojure",
+        "flavor": "None",
+        "orm": "Raw",
+        "platform": "Undertow",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "reitit",
+        "notes": "",
+        "versus": "Undertow"
+      }
+    },
+    {
+      "reactive": {
+        "db_url": "/db",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "Postgres",
+        "framework": "reitit",
+        "language": "Clojure",
+        "flavor": "None",
+        "orm": "Raw",
+        "platform": "Undertow",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "reitit-reactive",
+        "notes": "",
+        "versus": "Undertow"
+      }
     }
-  }]
+  ]
 }

+ 4 - 5
frameworks/Clojure/reitit/project.clj

@@ -1,12 +1,11 @@
 (defproject hello "reitit"
   :description "Immutant-nio, Reitit, Jsonista & Porsas"
   :dependencies [[org.clojure/clojure "1.10.0"]
-                 [ikitommi/immutant-web "3.0.0-alpha3"]
+                 [ikitommi/immutant-web "3.0.0-alpha4"]
+                 [metosin/reitit "0.3.7"]
                  [metosin/jsonista "0.2.2"]
-                 [hikari-cp "2.7.1"]
-                 [org.postgresql/postgresql "42.2.5"]
-                 [metosin/porsas "0.0.1-alpha4"]
-                 [metosin/reitit "0.3.4"]]
+                 [metosin/porsas "0.0.1-alpha10"]
+                 [hikari-cp "2.7.1"]]
   :jvm-opts ^:replace ["-Dclojure.compiler.direct-linking=true"]
   :main hello.handler
   :aot :all)

+ 6 - 0
frameworks/Clojure/reitit/reitit-reactive.dockerfile

@@ -0,0 +1,6 @@
+FROM clojure:lein-2.8.1
+WORKDIR /reitit
+COPY src src
+COPY project.clj project.clj
+RUN lein uberjar
+CMD ["java", "-server", "-Xms2G", "-Xmx2G", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-jar", "target/hello-reitit-standalone.jar", "async"]

+ 47 - 21
frameworks/Clojure/reitit/src/hello/handler.clj

@@ -3,6 +3,7 @@
             [hikari-cp.core :as hikari]
             [reitit.ring :as ring]
             [porsas.core :as p]
+            [porsas.async :as pa]
             [jsonista.core :as j])
   (:import (java.util.concurrent ThreadLocalRandom))
   (:gen-class))
@@ -10,15 +11,9 @@
 (defn random []
   (unchecked-inc (.nextInt (ThreadLocalRandom/current) 10000)))
 
-(def query-one (:query-one (p/compile {:row (p/rs->compiled-record)})))
-
-(defn random-world [ds]
-  (with-open [con (p/get-connection ds)]
-    (query-one con ["SELECT id, randomnumber from WORLD where id=?" (random)])))
-
 (defn plain-text-handler [_]
   {:status 200
-   :headers {"content-type" "text/plain; charset=utf-8"}
+   :headers {"content-type" "text/plain"}
    :body (.getBytes "Hello, World!")})
 
 (defn json-handler [_]
@@ -26,30 +21,61 @@
    :headers {"Content-Type" "application/json"}
    :body (j/write-value-as-bytes {:message "Hello, World!"})})
 
-(defn db-handler [ds]
-  (fn [_]
-    {:status 200
-     :headers {"Content-Type" "application/json"}
-     :body (j/write-value-as-bytes (random-world ds))}))
+(defn sync-db-handler [pool]
+  (let [mapper (p/data-mapper {:row (p/rs->compiled-record)})]
+    (fn [_]
+      (let [world (with-open [con (p/get-connection pool)]
+                    (p/query-one mapper con ["SELECT id, randomnumber from WORLD where id=?" (random)]))]
+        {:status 200
+         :headers {"Content-Type" "application/json"}
+         :body (j/write-value-as-bytes world)}))))
+
+(defn async-db-handler [pool]
+  (let [mapper (pa/data-mapper {:row (pa/rs->compiled-record)})]
+    (fn [_ respond _]
+      (pa/query-one
+        mapper
+        pool
+        ["SELECT id, randomnumber from WORLD where id=$1" (random)]
+        (fn [world]
+          (respond
+            {:status 200
+             :headers {"Content-Type" "application/json"}
+             :body (j/write-value-as-bytes world)}))
+        (fn [^Exception exception]
+          (respond
+            {:status 500
+             :headers {"content-type" "text/plain"}
+             :body (.getMessage exception)}))))))
 
-(defn -main [& _]
-  (let [ds (hikari/make-datasource
-             {:jdbc-url "jdbc:postgresql://tfb-database:5432/hello_world"
-              :username "benchmarkdbuser"
-              :password "benchmarkdbpass"
-              :maximum-pool-size 256})]
+(defn -main [& [async?]]
+  (let [cpus (.availableProcessors (Runtime/getRuntime))
+        pool (if async?
+               (pa/pool
+                 {:uri "postgresql://tfb-database:5432/hello_world"
+                  :user "benchmarkdbuser"
+                  :password "benchmarkdbpass"
+                  :size 64})
+               (hikari/make-datasource
+                 {:jdbc-url "jdbc:postgresql://tfb-database:5432/hello_world"
+                  :username "benchmarkdbuser"
+                  :password "benchmarkdbpass"
+                  :maximum-pool-size 256}))
+        db-handler (if async?
+                     (web/async (async-db-handler pool))
+                     (web/dispatch (sync-db-handler pool)))]
     (web/run
       (ring/ring-handler
         (ring/router
           [["/plaintext" (web/constantly plain-text-handler)]
            ["/json" json-handler]
-           ["/db" (web/dispatch (db-handler ds))]])
+           ["/db" db-handler]])
         (ring/create-default-handler)
         {:inject-match? false
          :inject-router? false})
       {:port 8080
        :host "0.0.0.0"
        :dispatch? false
-       :io-threads (* 2 (.availableProcessors (Runtime/getRuntime)))
-       :worker-threads (* 8 (.availableProcessors (Runtime/getRuntime)))
+       :io-threads (* 2 cpus)
+       :worker-threads 256
        :server {:always-set-keep-alive false}})))