diff --git a/frameworks/Clojure/kit/benchmark_config.json b/frameworks/Clojure/kit/benchmark_config.json index f5e13d358bb..bbde2d31918 100755 --- a/frameworks/Clojure/kit/benchmark_config.json +++ b/frameworks/Clojure/kit/benchmark_config.json @@ -25,6 +25,24 @@ "display_name": "Kit", "notes": "", "versus": "None" + }, + "majavat": { + "fortune_url": "/majavat-fortunes", + "port": 8080, + "approach": "Realistic", + "classification": "Platform", + "database": "postgres", + "framework": "None", + "language": "Clojure", + "flavor": "None", + "orm": "Raw", + "platform": "None", + "webserver": "None", + "os": "Linux", + "database_os": "Linux", + "display_name": "kit-majavat", + "notes": "", + "versus": "kit" } } ] diff --git a/frameworks/Clojure/kit/deps.edn b/frameworks/Clojure/kit/deps.edn index 29ff4d19400..50a41284745 100644 --- a/frameworks/Clojure/kit/deps.edn +++ b/frameworks/Clojure/kit/deps.edn @@ -1,29 +1,31 @@ {:paths ["src/clj" "resources"] - :deps {org.clojure/clojure {:mvn/version "1.11.1"} + :deps {org.clojure/clojure {:mvn/version "1.12.3"} ;; Routing - metosin/reitit {:mvn/version "0.5.18"} + metosin/reitit {:mvn/version "0.9.1"} ;; Ring - metosin/ring-http-response {:mvn/version "0.9.3"} - ring/ring-core {:mvn/version "1.9.5"} + metosin/ring-http-response {:mvn/version "0.9.5"} + ring/ring-core {:mvn/version "1.15.3"} ;; Data coercion - metosin/muuntaja {:mvn/version "0.6.8"} + metosin/muuntaja {:mvn/version "0.6.11"} ;; HTML templating - selmer/selmer {:mvn/version "1.12.55"} + selmer/selmer {:mvn/version "1.12.62"} + org.clojars.jj/majavat {:mvn/version "1.12.1"} ;; Database - org.postgresql/postgresql {:mvn/version "42.5.1"} + org.postgresql/postgresql {:mvn/version "42.7.8"} + ;; kit Libs - io.github.kit-clj/kit-core {:mvn/version "1.0.3"} - io.github.kit-clj/kit-undertow {:mvn/version "1.0.4"} - io.github.kit-clj/kit-sql-hikari {:mvn/version "1.0.2"} - org.clojure/core.cache {:mvn/version "1.0.225"} + io.github.kit-clj/kit-core {:mvn/version "1.0.9"} + io.github.kit-clj/kit-undertow {:mvn/version "1.0.9"} + io.github.kit-clj/kit-sql-hikari {:mvn/version "1.0.6"} + org.clojure/core.cache {:mvn/version "1.1.234"} } diff --git a/frameworks/Clojure/kit/kit-majavat.dockerfile b/frameworks/Clojure/kit/kit-majavat.dockerfile new file mode 100644 index 00000000000..55b27b6f122 --- /dev/null +++ b/frameworks/Clojure/kit/kit-majavat.dockerfile @@ -0,0 +1,19 @@ +# syntax = docker/dockerfile:1.2 +FROM clojure:openjdk-17 AS build + +WORKDIR / +COPY . / + +RUN clj -Sforce -T:build all + +FROM azul/zulu-openjdk-alpine:17 + +COPY --from=build /target/te-bench-standalone.jar /te-bench/te-bench-standalone.jar + +EXPOSE 8080 + +ENV PORT=8080 +ENV JAVA_OPTS="-XX:+UseContainerSupport -Dfile.encoding=UTF-8" +ENV JDBC_URL="jdbc:postgresql://tfb-database/hello_world?user=benchmarkdbuser&password=benchmarkdbpass" + +ENTRYPOINT exec java $JAVA_OPTS -jar /te-bench/te-bench-standalone.jar diff --git a/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/core.clj b/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/core.clj index 872d2d31334..fe893e40441 100644 --- a/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/core.clj +++ b/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/core.clj @@ -17,11 +17,10 @@ ;; log uncaught exceptions in threads (Thread/setDefaultUncaughtExceptionHandler - (reify Thread$UncaughtExceptionHandler - (uncaughtException [_ thread ex] - (log/error {:what :uncaught-exception - :exception ex - :where (str "Uncaught exception on" (.getName thread))})))) + (fn [thread ex] + (log/error {:what :uncaught-exception + :exception ex + :where (str "Uncaught exception on" (.getName thread))}))) (defonce system (atom nil)) diff --git a/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/web/controllers/bench.clj b/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/web/controllers/bench.clj index 71cda1008ec..0ac7c6f2b2b 100644 --- a/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/web/controllers/bench.clj +++ b/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/web/controllers/bench.clj @@ -3,6 +3,9 @@ [clojure.core.cache :as cache] [next.jdbc :as jdbc] [next.jdbc.result-set :as rs] + [jj.majavat :as majavat] + [jj.majavat.renderer :refer [->InputStreamRenderer]] + [jj.majavat.renderer.sanitizer :refer [->Html]] [ring.util.http-response :as http-response] [selmer.parser :as parser])) @@ -13,15 +16,24 @@ (def ^:const HELLO_WORLD "Hello, World!") (def ^:const MAX_ID_ZERO_IDX 9999) (def ^:const CACHE_TTL (* 24 60 60)) - +(def ^:private render-fortune (majavat/build-renderer "html/fortunes.html" + {:renderer (->InputStreamRenderer + {:sanitizer (->Html)})})) (def selmer-opts {:custom-resource-path (clojure.java.io/resource "html")}) -(defn html-response +(defn selmer-html-response [template & [params]] (-> (parser/render-file template params selmer-opts) (http-response/ok) (http-response/content-type "text/html; charset=utf-8"))) +(defn majavat-html-response + [context] + (-> (render-fortune context) + (http-response/ok) + (http-response/content-type "text/html; charset=utf-8"))) + + (defn rand-id [n] (inc (rand-int n))) @@ -31,7 +43,7 @@ "Parse provided string value of query count, clamping values to between 1 and 500." [^String queries] (let [n (try (Integer/parseInt queries) - (catch Exception _ 1))] ; default to 1 on parse failure + (catch Exception _ 1))] ; default to 1 on parse failure (cond (< n 1) 1 (> n 500) 500 @@ -101,7 +113,7 @@ (defn update-db-handler [db-conn request] - (let [items (db-multi-query-world! db-conn request)] + (let [items (db-multi-query-world! db-conn request)] (http-response/ok (mapv (fn [{:keys [id]}] @@ -122,9 +134,16 @@ [] (range-from-req request)))) -(defn fortune-handler +(defn selmer-fortune-handler + [db-conn _request] + (as-> (jdbc/execute! db-conn ["select * from \"Fortune\";"] jdbc-opts) fortunes + (conj fortunes {:id 0 :message "Additional fortune added at request time."}) + (sort-by :message fortunes) + (selmer-html-response "fortunes.html" {:messages fortunes}))) + +(defn majavat-fortune-handler [db-conn _request] (as-> (jdbc/execute! db-conn ["select * from \"Fortune\";"] jdbc-opts) fortunes (conj fortunes {:id 0 :message "Additional fortune added at request time."}) (sort-by :message fortunes) - (html-response "fortunes.html" {:messages fortunes}))) \ No newline at end of file + (majavat-html-response {:messages fortunes}))) \ No newline at end of file diff --git a/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/web/routes/bench.clj b/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/web/routes/bench.clj index 2b81a381c86..032ceb143f7 100644 --- a/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/web/routes/bench.clj +++ b/frameworks/Clojure/kit/src/clj/io/github/kit_clj/te_bench/web/routes/bench.clj @@ -17,7 +17,8 @@ ["/queries" {:get (partial bench/multi-db-handler db-conn)}] ["/updates" {:get (partial bench/update-db-handler db-conn)}] ["/cached-queries" {:get (partial bench/cached-query-handler db-conn cache)}] - ["/fortunes" {:get (partial bench/fortune-handler db-conn)}]]) + ["/fortunes" {:get (partial bench/selmer-fortune-handler db-conn)}] + ["/majavat-fortunes" {:get (partial bench/majavat-fortune-handler db-conn)}]]) (defmethod ig/init-key :reitit.routes/bench [_ {:keys [base-path] @@ -25,10 +26,7 @@ :as opts}] [base-path {:muuntaja formats/instance - :middleware [;; query-params & form-params - parameters/parameters-middleware - ;; encoding response body + :middleware [parameters/parameters-middleware muuntaja/format-response-middleware - ;; default header middleware default-headers/default-headers-middleware]} (bench-routes opts)]) diff --git a/frameworks/Clojure/ring-http-exchange/benchmark_config.json b/frameworks/Clojure/ring-http-exchange/benchmark_config.json index 0d7e64dcf6a..d8d2ba0ce3e 100755 --- a/frameworks/Clojure/ring-http-exchange/benchmark_config.json +++ b/frameworks/Clojure/ring-http-exchange/benchmark_config.json @@ -5,14 +5,15 @@ "default": { "json_url": "/json", "plaintext_url": "/plaintext", + "fortune_url": "/fortunes", "port": 8080, "approach": "Realistic", "classification": "Platform", - "database": "None", + "database": "postgres", "framework": "None", "language": "Clojure", "flavor": "None", - "orm": "None", + "orm": "Raw", "platform": "None", "webserver": "None", "os": "Linux", @@ -24,14 +25,15 @@ "robaho": { "json_url": "/json", "plaintext_url": "/plaintext", + "fortune_url": "/fortunes", "port": 8080, "approach": "Realistic", "classification": "Platform", - "database": "None", + "database": "postgres", "framework": "None", "language": "Clojure", "flavor": "None", - "orm": "None", + "orm": "Raw", "platform": "None", "webserver": "None", "os": "Linux", @@ -43,14 +45,15 @@ "graalvm": { "json_url": "/json", "plaintext_url": "/plaintext", + "fortune_url": "/fortunes", "port": 8080, "approach": "Realistic", "classification": "Platform", - "database": "None", + "database": "postgres", "framework": "None", "language": "Clojure", "flavor": "None", - "orm": "None", + "orm": "Raw", "platform": "None", "webserver": "None", "os": "Linux", @@ -62,14 +65,15 @@ "robaho-graalvm": { "json_url": "/json", "plaintext_url": "/plaintext", + "fortune_url": "/fortunes", "port": 8080, "approach": "Realistic", "classification": "Platform", - "database": "None", + "database": "postgres", "framework": "None", "language": "Clojure", "flavor": "None", - "orm": "None", + "orm": "Raw", "platform": "None", "webserver": "None", "os": "Linux", diff --git a/frameworks/Clojure/ring-http-exchange/config.toml b/frameworks/Clojure/ring-http-exchange/config.toml index 48ba799aef5..17193d6169a 100644 --- a/frameworks/Clojure/ring-http-exchange/config.toml +++ b/frameworks/Clojure/ring-http-exchange/config.toml @@ -4,9 +4,10 @@ name = "ring-http-exchange" [main] urls.plaintext = "/plaintext" urls.json = "/json" +urls.fortune = "/fortunes" approach = "Realistic" classification = "Platform" -database = "None" +database = "postgres" database_os = "Linux" os = "Linux" orm = "Raw" @@ -18,9 +19,10 @@ versus = "httpserver" [graalvm] urls.plaintext = "/plaintext" urls.json = "/json" +urls.fortune = "/fortunes" approach = "Realistic" classification = "Platform" -database = "None" +database = "postgres" database_os = "Linux" os = "Linux" orm = "Raw" @@ -31,9 +33,10 @@ versus = "httpserver-graalvm" [robaho] urls.plaintext = "/plaintext" urls.json = "/json" +urls.fortune = "/fortunes" approach = "Realistic" classification = "Platform" -database = "None" +database = "postgres" database_os = "Linux" os = "Linux" orm = "Raw" @@ -44,9 +47,10 @@ versus = "httpserver-robaho" [robaho-graalvm] urls.plaintext = "/plaintext" urls.json = "/json" +urls.fortune = "/fortunes" approach = "Realistic" classification = "Platform" -database = "None" +database = "postgres" database_os = "Linux" os = "Linux" orm = "Raw" diff --git a/frameworks/Clojure/ring-http-exchange/pom.xml b/frameworks/Clojure/ring-http-exchange/pom.xml deleted file mode 100644 index bee1ed47c88..00000000000 --- a/frameworks/Clojure/ring-http-exchange/pom.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - 4.0.0 - ring-http-server - ring-http-server - jar - 1.0.0 - ring-http-server - - - EPL-2.0 - https://www.eclipse.org/legal/epl-2.0/ - - - - java - java-test - - - resources - - - - - resources - - - target - target\classes - - - com.theoryinpractise - clojure-maven-plugin - 1.8.3 - true - - - compile-clojure - compile - - compile - - - - test-clojure - test - - test - - - - - - src/ - - - - - maven-assembly-plugin - - - - ring_http_exchange.benchmark - - - - jar-with-dependencies - - - - - make-assembly - package - - single - - - - - - - - - central - https://repo1.maven.org/maven2/ - - false - - - true - - - - clojars - https://repo.clojars.org/ - - true - - - true - - - - - - - - - org.clojure - clojure - 1.11.2 - - - org.clojars.jj - ring-http-exchange - 1.2.0 - - - metosin - jsonista - 0.3.13 - - - - - robaho - - false - - - - io.github.robaho - httpserver - 1.0.23 - - - - - diff --git a/frameworks/Clojure/ring-http-exchange/project.clj b/frameworks/Clojure/ring-http-exchange/project.clj new file mode 100644 index 00000000000..de2033a7550 --- /dev/null +++ b/frameworks/Clojure/ring-http-exchange/project.clj @@ -0,0 +1,21 @@ +(defproject ring-http-server "1.0.0" + :description "ring benchmark" + :url "" + :license {:name "EPL-2.0" + :url "https://www.eclipse.org/legal/epl-2.0/"} + + :dependencies [[org.clojure/clojure "1.12.3"] + [org.clojure/tools.logging "1.3.0"] + [org.clojars.jj/ring-http-exchange "1.2.4"] + [seancorfield/next.jdbc "1.2.659"] + [org.clojars.jj/majavat "1.12.1"] + [hikari-cp "3.3.0"] + [org.postgresql/postgresql "42.7.8"] + [metosin/jsonista "0.3.13"] + ] + + :profiles {:robaho {:dependencies [[io.github.robaho/httpserver "1.0.28"]]}} + :resource-paths ["resources"] + :main ring-http-exchange.benchmark + + ) diff --git a/frameworks/Clojure/ring-http-exchange/resources/fortune.html b/frameworks/Clojure/ring-http-exchange/resources/fortune.html new file mode 100644 index 00000000000..3f4dd2fca9e --- /dev/null +++ b/frameworks/Clojure/ring-http-exchange/resources/fortune.html @@ -0,0 +1,15 @@ + + +Fortunes + + + + {% for message in messages %} + + + + + {% endfor %} +
idmessage
{{message.id}}{{message.message}}
+ + \ No newline at end of file diff --git a/frameworks/Clojure/ring-http-exchange/ring-http-exchange-graalvm.dockerfile b/frameworks/Clojure/ring-http-exchange/ring-http-exchange-graalvm.dockerfile index f2aed8bf3d7..1d9e25ecef6 100644 --- a/frameworks/Clojure/ring-http-exchange/ring-http-exchange-graalvm.dockerfile +++ b/frameworks/Clojure/ring-http-exchange/ring-http-exchange-graalvm.dockerfile @@ -1,12 +1,13 @@ -FROM maven:3-eclipse-temurin-24-alpine as maven +FROM clojure:lein as lein WORKDIR /ring-http-exchange -COPY pom.xml pom.xml +COPY project.clj project.clj +COPY resources resources COPY src src -RUN mvn clean clojure:compile package +RUN lein uberjar FROM ghcr.io/graalvm/graalvm-community:24 WORKDIR /ring-http-exchange -COPY --from=maven /ring-http-exchange/target/ring-http-server-1.0.0-jar-with-dependencies.jar app.jar +COPY --from=lein /ring-http-exchange/target/ring-http-server-1.0.0-standalone.jar app.jar EXPOSE 8080 diff --git a/frameworks/Clojure/ring-http-exchange/ring-http-exchange-robaho-graalvm.dockerfile b/frameworks/Clojure/ring-http-exchange/ring-http-exchange-robaho-graalvm.dockerfile index 1783b1878eb..1362b411aed 100644 --- a/frameworks/Clojure/ring-http-exchange/ring-http-exchange-robaho-graalvm.dockerfile +++ b/frameworks/Clojure/ring-http-exchange/ring-http-exchange-robaho-graalvm.dockerfile @@ -1,12 +1,13 @@ -FROM maven:3-eclipse-temurin-24-alpine as maven +FROM clojure:lein as lein WORKDIR /ring-http-exchange -COPY pom.xml pom.xml +COPY project.clj project.clj +COPY resources resources COPY src src -RUN mvn clean clojure:compile -P robaho package +RUN lein with-profile robaho uberjar FROM ghcr.io/graalvm/graalvm-community:24 WORKDIR /ring-http-exchange -COPY --from=maven /ring-http-exchange/target/ring-http-server-1.0.0-jar-with-dependencies.jar app.jar +COPY --from=lein /ring-http-exchange/target/ring-http-server-1.0.0-standalone.jar app.jar EXPOSE 8080 diff --git a/frameworks/Clojure/ring-http-exchange/ring-http-exchange-robaho.dockerfile b/frameworks/Clojure/ring-http-exchange/ring-http-exchange-robaho.dockerfile index 55be60f11f4..e31848de2e6 100644 --- a/frameworks/Clojure/ring-http-exchange/ring-http-exchange-robaho.dockerfile +++ b/frameworks/Clojure/ring-http-exchange/ring-http-exchange-robaho.dockerfile @@ -1,12 +1,13 @@ -FROM maven:3-eclipse-temurin-24-alpine as maven +FROM clojure:lein as lein WORKDIR /ring-http-exchange -COPY pom.xml pom.xml +COPY project.clj project.clj +COPY resources resources COPY src src -RUN mvn clean clojure:compile -P robaho package +RUN lein with-profile robaho uberjar FROM openjdk:25-jdk-slim WORKDIR /ring-http-exchange -COPY --from=maven /ring-http-exchange/target/ring-http-server-1.0.0-jar-with-dependencies.jar app.jar +COPY --from=lein /ring-http-exchange/target/ring-http-server-1.0.0-standalone.jar app.jar EXPOSE 8080 diff --git a/frameworks/Clojure/ring-http-exchange/ring-http-exchange.dockerfile b/frameworks/Clojure/ring-http-exchange/ring-http-exchange.dockerfile index fe3b450b87a..b558aa938cf 100644 --- a/frameworks/Clojure/ring-http-exchange/ring-http-exchange.dockerfile +++ b/frameworks/Clojure/ring-http-exchange/ring-http-exchange.dockerfile @@ -1,12 +1,13 @@ -FROM maven:3-eclipse-temurin-24-alpine as maven +FROM clojure:lein as lein WORKDIR /ring-http-exchange -COPY pom.xml pom.xml +COPY project.clj project.clj +COPY resources resources COPY src src -RUN mvn clean clojure:compile package +RUN lein uberjar FROM openjdk:25-jdk-slim WORKDIR /ring-http-exchange -COPY --from=maven /ring-http-exchange/target/ring-http-server-1.0.0-jar-with-dependencies.jar app.jar +COPY --from=lein /ring-http-exchange/target/ring-http-server-1.0.0-standalone.jar app.jar EXPOSE 8080 diff --git a/frameworks/Clojure/ring-http-exchange/src/ring_http_exchange/benchmark.clj b/frameworks/Clojure/ring-http-exchange/src/ring_http_exchange/benchmark.clj index 1f7c448e279..95341069bc2 100644 --- a/frameworks/Clojure/ring-http-exchange/src/ring_http_exchange/benchmark.clj +++ b/frameworks/Clojure/ring-http-exchange/src/ring_http_exchange/benchmark.clj @@ -1,29 +1,59 @@ (ns ring-http-exchange.benchmark - (:gen-class) - (:require [jsonista.core :as json] - [ring-http-exchange.core :as server]) - (:import - (java.util.concurrent Executors))) + (:gen-class) + (:require + [jsonista.core :as json] + [jj.majavat :as majavat] + [jj.majavat.renderer :refer [->InputStreamRenderer]] + [jj.majavat.renderer.sanitizer :refer [->Html]] + [ring-http-exchange.core :as server] + [next.jdbc :as jdbc] + [next.jdbc.connection :as connection]) + (:import + (com.zaxxer.hikari HikariDataSource) + (java.util.concurrent Executors))) +(def db-spec + {:jdbcUrl "jdbc:postgresql://tfb-database/hello_world?user=benchmarkdbuser&password=benchmarkdbpass"}) + +(def datasource + (connection/->pool HikariDataSource db-spec)) + +(defn query-fortunes [] + (jdbc/execute! datasource + ["SELECT * FROM \"Fortune\""] + {:builder-fn next.jdbc.result-set/as-unqualified-lower-maps})) + +(def ^:private ^:const additional-message {:id 0 + :message "Additional fortune added at request time."}) +(def ^:private ^:const fortune-headers {"Server" "ring-http-exchange" + "Content-Type" "text/html; charset=UTF-8"}) (def ^:private ^:const json-headers {"Server" "ring-http-exchange" "Content-Type" "application/json"}) -(def ^:private ^:const plaintext-response - {:status 200 - :headers { - "Server" "ring-http-exchange" - "Content-Type" "text/plain"} - :body "Hello, World!"}) +(def ^:private ^:const plaintext-response {:status 200 + :headers {"Server" "ring-http-exchange" + "Content-Type" "text/plain"} + :body "Hello, World!"}) +(def ^:private render-fortune (majavat/build-renderer "fortune.html" + {:renderer (->InputStreamRenderer + {:sanitizer (->Html)})})) (defn -main - [& args] - (println "Starting server on port 8080") - (server/run-http-server - (fn [req] - (case (req :uri) - "/json" {:status 200 - :headers json-headers - :body (json/write-value-as-bytes {:message "Hello, World!"})} - plaintext-response)) - {:port 8080 - :host "0.0.0.0" - :executor (Executors/newVirtualThreadPerTaskExecutor)})) + [& _] + (println "Starting server on port 8080") + (server/run-http-server + (fn [req] + (case (req :uri) + "/json" {:status 200 + :headers json-headers + :body (json/write-value-as-bytes {:message "Hello, World!"})} + "/fortunes" (let [input (as-> (query-fortunes) fortunes + (conj fortunes additional-message) + (sort-by :message fortunes)) + body (render-fortune {:messages input})] + {:status 200 + :headers fortune-headers + :body body}) + plaintext-response)) + {:port 8080 + :host "0.0.0.0" + :executor (Executors/newVirtualThreadPerTaskExecutor)})) \ No newline at end of file