Skip to content

Commit

Permalink
Enable *warn-on-reflection* and add missing hints (#18)
Browse files Browse the repository at this point in the history
At the moment there are several reflection calls occuring on the
hot-path for request handling. This is both slow and makes it harder to
compile with GraalVM.

This commit enables the `*warn-on-reflection*` global on all namespaces
and adds the missing type hints to locations where reflection were
occuring.

In some cases this required restructuring code a bit to better apply the
hints.
  • Loading branch information
julienvincent authored Jan 12, 2024
1 parent dd0c034 commit 6e894fb
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 25 deletions.
38 changes: 21 additions & 17 deletions src/s_exp/hirundo/http/request.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
(io.helidon.http HttpPrologue Headers Header)
(io.helidon.webserver.http ServerRequest ServerResponse)))

(set! *warn-on-reflection* true)

(defn ring-headers
[^Headers headers]
(-> (reduce (fn [m ^Header h]
Expand Down Expand Up @@ -49,21 +51,23 @@
(let [qs (ring-query (.query server-request))
body (let [content (.content server-request)]
(when-not (.consumed content) (.inputStream content)))
ring-request (-> (.asTransient PersistentHashMap/EMPTY)
(.assoc :server-port (.port (.localPeer server-request)))
(.assoc :server-name (.host (.localPeer server-request)))
(.assoc :remote-addr (let [address ^java.net.InetSocketAddress (.address (.remotePeer server-request))]
(-> address .getAddress .getHostAddress)))
(.assoc :ssl-client-cert (some-> server-request .remotePeer .tlsCertificates (.orElse nil) first))
(.assoc :uri (ring-path (.path server-request)))
(.assoc :scheme (if (.isSecure server-request) :https :http))
(.assoc :protocol (ring-protocol (.prologue server-request)))
(.assoc :request-method (ring-method (.prologue server-request)))
(.assoc :headers (ring-headers (.headers server-request)))
(.assoc ::server-request server-request)
(.assoc ::server-response server-response))
;; optional

ring-request (transient
{:server-port (.port (.localPeer server-request))
:server-name (.host (.localPeer server-request))
:remote-addr (let [address ^java.net.InetSocketAddress (.address (.remotePeer server-request))]
(-> address .getAddress .getHostAddress))
:ssl-client-cert (some-> server-request .remotePeer .tlsCertificates (.orElse nil) first)
:uri (ring-path (.path server-request))
:scheme (if (.isSecure server-request) :https :http)
:protocol (ring-protocol (.prologue server-request))
:request-method (ring-method (.prologue server-request))
:headers (ring-headers (.headers server-request))
::server-request server-request
::server-response server-response})

ring-request (cond-> ring-request
qs (.assoc :query-string (ring-query (.query server-request)))
body (.assoc :body body))]
(.persistent ring-request)))
qs (assoc! :query-string (ring-query (.query server-request)))
body (assoc! :body body))]

(persistent! ring-request)))
15 changes: 7 additions & 8 deletions src/s_exp/hirundo/http/response.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
(io.helidon.webserver.http ServerResponse)
(java.io FileInputStream InputStream OutputStream)))

(set! *warn-on-reflection* true)

(def ring-core-available?
(try
(require 'ring.core.protocols)
Expand Down Expand Up @@ -44,12 +46,12 @@
(when ring-core-available?
(extend-protocol BodyWriter
Object
(write-body! [o server-response]
(write-body! [o ^ServerResponse server-response]
(let [StreamableResponseBody @(ns-resolve 'ring.core.protocols 'StreamableResponseBody)
write-body-to-stream (ns-resolve 'ring.core.protocols 'write-body-to-stream)]
(if (satisfies? StreamableResponseBody o)
(write-body-to-stream o nil (.outputStream server-response))
(.send ^ServerResponse server-response o))))))
(.send server-response o))))))

(defn header-name ^HeaderName [ring-header-name]
(HeaderNames/createFromLowercase (name ring-header-name)))
Expand All @@ -58,12 +60,9 @@
[^ServerResponse server-response headers]
(when headers
(run! (fn [[k v]]
(.header server-response
(header-name k)
(if (sequential? v)
(into-array String v)
(doto (make-array String 1)
(aset 0 v)))))
(let [values-seq (if (sequential? v) v [v])
headers ^"[Ljava.lang.String;" (into-array String values-seq)]
(.header server-response (header-name k) headers)))
headers)))

(defn- set-status!
Expand Down
2 changes: 2 additions & 0 deletions src/s_exp/hirundo/utils.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
(ns s-exp.hirundo.utils
(:require [clojure.string :as str]))

(set! *warn-on-reflection* true)

(defn camel->dashed
[s]
(-> s
Expand Down

0 comments on commit 6e894fb

Please sign in to comment.