Browse Source

Update clojure/reitit to use metosin/pohjavirta as web server (#4913)

* Change clojure/reitit webserver to metosin/pohjavirta

* Benchmark using different pool sizes

* Fix tests
Tommi Reiman 6 years ago
parent
commit
4af40c1242

+ 2 - 2
frameworks/Clojure/reitit/README.md

@@ -1,6 +1,6 @@
 # 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, 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).
+This is the [Reitit](https://github.com/metosin/reitit) portion of a [benchmarking test suite](../) comparing a variety of web development platforms, both witb JDBC via [HikariCP](https://github.com/tomekw/hikari-cp) and [The Reactive SQL Client](https://github.com/eclipse-vertx/vertx-sql-client).
 
 ### Source
 
@@ -12,7 +12,7 @@ The dependencies are documented in [project.clj](hello/project.clj),
 but the main ones are:
 
 * [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/pohjavirta](https://github.com/metosin/pohjavirta) - fast wrapper for [Undertow](http://undertow.io/)
 * [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

+ 181 - 2
frameworks/Clojure/reitit/benchmark_config.json

@@ -5,6 +5,25 @@
       "default": {
         "json_url": "/json",
         "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "None",
+        "framework": "reitit",
+        "language": "Clojure",
+        "flavor": "None",
+        "orm": "Raw",
+        "platform": "Undertow",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "reitit",
+        "notes": "",
+        "versus": "Undertow"
+      }
+    },
+    {
+      "jdbc16": {
         "db_url": "/db",
         "port": 8080,
         "approach": "Realistic",
@@ -18,13 +37,173 @@
         "webserver": "None",
         "os": "Linux",
         "database_os": "Linux",
-        "display_name": "reitit",
+        "display_name": "reitit-reactive",
+        "notes": "",
+        "versus": "Undertow"
+      }
+    },
+    {
+      "jdbc32": {
+        "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"
+      }
+    },
+    {
+      "jdbc64": {
+        "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"
+      }
+    },
+    {
+      "jdbc128": {
+        "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"
+      }
+    },
+    {
+      "jdbc256": {
+        "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"
+      }
+    },
+    {
+      "async16": {
+        "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"
+      }
+    },
+    {
+      "async32": {
+        "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"
+      }
+    },
+    {
+      "async64": {
+        "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"
+      }
+    },
+    {
+      "async128": {
+        "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"
       }
     },
     {
-      "reactive": {
+      "async256": {
         "db_url": "/db",
         "port": 8080,
         "approach": "Realistic",

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

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

+ 6 - 0
frameworks/Clojure/reitit/reitit-async128.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", "-Dvertx.disableMetrics=true", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-jar", "target/hello-reitit-standalone.jar", "async", "128"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-async16.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", "-Dvertx.disableMetrics=true", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-jar", "target/hello-reitit-standalone.jar", "async", "16"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-async256.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", "-Dvertx.disableMetrics=true", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-jar", "target/hello-reitit-standalone.jar", "async", "256"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-async32.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", "-Dvertx.disableMetrics=true", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-jar", "target/hello-reitit-standalone.jar", "async", "32"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-async64.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", "-Dvertx.disableMetrics=true", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-jar", "target/hello-reitit-standalone.jar", "async", "64"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-jdbc128.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", "sync", "128"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-jdbc16.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", "sync", "16"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-jdbc256.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", "sync", "256"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-jdbc32.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", "sync", "32"]

+ 6 - 0
frameworks/Clojure/reitit/reitit-jdbc64.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", "sync", "64"]

+ 56 - 58
frameworks/Clojure/reitit/src/hello/handler.clj

@@ -1,5 +1,6 @@
 (ns hello.handler
-  (:require [immutant.web :as web]
+  (:require [pohjavirta.server :as server]
+            [pohjavirta.async :as a]
             [hikari-cp.core :as hikari]
             [reitit.ring :as ring]
             [porsas.core :as p]
@@ -13,69 +14,66 @@
 
 (defn plain-text-handler [_]
   {:status 200
-   :headers {"content-type" "text/plain"}
-   :body (.getBytes "Hello, World!")})
+   :headers {"Content-Type" "text/plain"}
+   :body "Hello, World!"})
 
 (defn json-handler [_]
   {:status 200
    :headers {"Content-Type" "application/json"}
    :body (j/write-value-as-bytes {:message "Hello, World!"})})
 
-(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 sync-db-handler [mapper pool]
+  (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 async-db-handler [mapper pool]
+  (fn [_]
+    (-> (pa/query-one mapper pool ["SELECT id, randomnumber from WORLD where id=$1" (random)])
+        (pa/then (fn [world]
+                   {:status 200
+                    :headers {"Content-Type" "application/json"}
+                    :body (j/write-value-as-bytes world)})))))
 
-(defn -main [& [async?]]
+(defn -main [& [mode ?size]]
   (let [cpus (.availableProcessors (Runtime/getRuntime))
-        pool (if async?
-               (pa/pool
-                 {:uri "postgresql://tfb-database:5432/hello_world"
-                  :user "benchmarkdbuser"
-                  :password "benchmarkdbpass"
-                  :size 1})
-               (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" db-handler]])
-        (ring/create-default-handler)
-        {:inject-match? false
-         :inject-router? false})
-      {:port 8080
-       :host "0.0.0.0"
-       :dispatch? false
-       :io-threads (* 2 cpus)
-       :worker-threads 256
-       :server {:always-set-keep-alive false}})))
+        size (try (Integer/parseInt ?size) (catch Exception _ (* 2 cpus)))
+        db-handler (cond 
+                     ;; reactive pg-client 
+                     (= mode "async")
+                     (async-db-handler
+                       (pa/data-mapper {:row (pa/rs->compiled-record)})
+                       (pa/pool
+                         {:uri "postgresql://tfb-database:5432/hello_world"
+                          :user "benchmarkdbuser"
+                          :password "benchmarkdbpass"
+                          :size size}))
+                     ;; jdbc
+                     (= mode "sync")
+                     (sync-db-handler
+                       (p/data-mapper {:row (p/rs->compiled-record)})
+                       (hikari/make-datasource
+                         {:jdbc-url "jdbc:postgresql://tfb-database:5432/hello_world"
+                          :username "benchmarkdbuser"
+                          :password "benchmarkdbpass"
+                          :maximum-pool-size size}))
+                     ;; none
+                     :else (constantly nil))]
+    (println "Starting" mode "server, with pool-size" size)
+    (-> (ring/ring-handler
+          (ring/router
+            [["/plaintext" (server/constantly plain-text-handler)]
+             ["/json" json-handler]
+             ["/db" db-handler]])
+          (ring/create-default-handler)
+          {:inject-match? false
+           :inject-router? false})
+        (server/create
+          {:port 8080
+           :host "0.0.0.0"
+           :io-threads (* 2 cpus)
+           :worker-threads 256})
+        (server/start))))