Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic perforate benchmark based on the "things" resource #112

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions benchmarks/things_bench.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
(ns things-bench
(:require [liberator.core :refer (defresource request-method-in)]
[liberator.representation :refer (ring-response)]
[perforate.core :refer :all]
[ring.mock.request :refer (request header)])
(:import [java.security MessageDigest]))

(defresource thing-resource
[things]
;; early lookup
:service-available? (fn [ctx] {::r (get @things (get-in ctx [:request :uri]))})
:method-allowed? (request-method-in :get :put :delete)
;; lookup media types of the requested resource
:available-media-types #(if-let [m (get-in % [::r :media-type])] [m])
;; the resource exists if a value is stored in @things at the uri
;; store the looked up value at key ::r in the context
:exists? #(get % ::r)
;; ...it existed if the stored value is nil (and not some random
;; Objeced we use as a setinel)
:existed? #(nil? (get @things (get-in % [:request :uri]) (Object.)))
;; use the previously stored value at ::r
:handle-ok #(get-in % [::r :content])
;; update the representation
:put! #(dosync
(alter things assoc-in
[(get-in % [:request :uri])]
{:content (get-in % [:request :body])
:media-type (get-in % [:request :headers "content-type"]
"application/octet-stream")
:last-modified (java.util.Date.)}))
;; ...store a nil value to marke the resource as gone
:delete! #(dosync (alter things assoc (get-in % [:request :uri]) nil))
:last-modified #(get-in % [::r :last-modified]))

(defgoal things-bench "'Things' Resource benchmarks")

(defcase things-bench "Things"
[]
(let [t-r (thing-resource (ref nil))]
(let [resp (t-r (request :get "/r1"))]
(-> resp :status (= 404) assert))
(let [resp (t-r (-> (request :put "/r1")
(assoc :body "r1")
(header "content-type" "text/plain")))]
(-> resp :status (= 201) assert))
(let [resp (t-r (-> (request :get "/r1")))]
(-> resp :status (= 200) assert)
(-> resp :body (= "r1") assert)
(-> resp (get-in [:headers "Content-Type"])
(= "text/plain;charset=UTF-8")
assert))
(let [resp (t-r (-> (request :delete "/r1")))]
(-> resp :status (= 204) assert)
(-> resp :body nil? assert))
(let [resp (t-r (request :get "/r1"))]
(-> resp :status (= 410) assert))))
8 changes: 7 additions & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
:url "https://github.com/clojure-liberator/liberator"}

:plugins [[lein-midje "3.1.3" :exclusions [leiningen-core]]
[lein-ring "0.8.10" :exclusions [org.clojure/clojure]]]
[lein-ring "0.8.10" :exclusions [org.clojure/clojure]]
[perforate "0.3.3"]]

:profiles {:dev {:dependencies [[ring/ring-jetty-adapter "1.2.1" :exclusions [joda-time]]
[ring-mock "0.1.2"]
Expand All @@ -31,6 +32,11 @@
:source-paths ["src"]
:test-paths ["test"]

:perforate
{:environments [{:name :core
:profiles [:dev :1.5]
:namespaces [things-bench]}]}

:ring {:handler examples.server/handler
:adapter {:port 8000}}

Expand Down
6 changes: 3 additions & 3 deletions src/liberator/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@

(defmethod to-location clojure.lang.APersistentMap [this] this)

(defmethod to-location java.net.URL [url] (to-location (.toString url)))
(defmethod to-location java.net.URL [^java.net.URL url] (to-location (.toString url)))

(defmethod to-location nil [this] this)

Expand Down Expand Up @@ -335,7 +335,7 @@

(defdecision modified-since?
(fn [context]
(let [last-modified (gen-last-modified context)]
(let [^java.util.Date last-modified (gen-last-modified context)]
[(and last-modified (.after last-modified (::if-modified-since-date context)))
{::last-modified last-modified}]))
method-delete?
Expand Down Expand Up @@ -371,7 +371,7 @@

(defdecision unmodified-since?
(fn [context]
(let [last-modified (gen-last-modified context)]
(let [^java.util.Date last-modified (gen-last-modified context)]
[(and last-modified
(.after last-modified
(::if-unmodified-since-date context)))
Expand Down
2 changes: 1 addition & 1 deletion src/liberator/representation.clj
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
(render-seq-generic data (assoc-in context [:representation :media-type]
"application/json"))))

(defn in-charset [string charset]
(defn in-charset [^String string ^String charset]
(if (and charset (not (.equalsIgnoreCase charset "UTF-8")))
(java.io.ByteArrayInputStream.
(.getBytes string (java.nio.charset.Charset/forName charset)))
Expand Down
4 changes: 2 additions & 2 deletions src/liberator/util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
nil
(as-date [this] nil))

(defn http-date-format []
(defn ^SimpleDateFormat http-date-format []
(let [df (new SimpleDateFormat
"EEE, dd MMM yyyy HH:mm:ss z"
Locale/US)]
(do (.setTimeZone df (TimeZone/getTimeZone "GMT"))
df)))

(defn relative-date [future]
(Date. (+ (System/currentTimeMillis) future)))
(Date. (long (+ (System/currentTimeMillis) future))))

(defn http-date [date]
(format "%s" (.format (http-date-format) date)))
Expand Down