(ns benchmark (:import java.lang.System java.util.Random) (:use compojure clojure.contrib.json.write)) (defstruct user-struct :nick :last-seen) (defstruct message-struct :nick :content :timestamp) (def room-limit 100) (def message-log-size 100) (def users (ref {})) (def messages (ref [])) (def random (new Random)) ;define characters list to use to generate string (def chars (map char (concat (range 48 58) (range 66 92) (range 97 123)))) ;generates 1 random character (defn random-char [] (nth chars (.nextInt random (count chars)))) ; generates random string of length characters (defn random-string [length] (apply str (take length (repeatedly random-char)))) (defn pick [s] (nth (seq s) (. random nextInt (count s)))) (defn refresh [] (dosync {"users" (keys @users) "messages" @messages})) (defn add-user [] (dosync (if (= (count @users) room-limit) (let [loser (pick (keys @users))] (alter users dissoc loser))) (let [nick (random-string 10)] (alter users assoc nick (struct user-struct nick (System/currentTimeMillis))) {"users" (keys @users) "messages" (reverse @messages)}))) (defn post-message [] (dosync (let [nick (pick (keys @users)) msg (random-string 30)] (ref-set messages (conj (take (- 100 1) @messages) (struct message-struct nick msg (System/currentTimeMillis)))) (alter users assoc-in [nick :last-seen] (System/currentTimeMillis)) "OK"))) (defn out [x] "out") (defn do-bench [] (let [r (.nextDouble random)] (cond (< r 0.8) (out (refresh)) (< r 0.9) (out (add-user)) (< r 1) (out (post-message))))) (defn hello-world [] "hello world!") (defroutes benchmark (GET "/hello" (hello-world)) (ANY "*" (do-bench))) (add-user) (run-server {:port 8080} "/*" (servlet benchmark))