From e659e98b13850bf6e1e717291d5b7a596b76e403 Mon Sep 17 00:00:00 2001 From: Christian Mueller Date: Sat, 29 Mar 2014 16:08:51 +0100 Subject: [PATCH] LRU cache for note pages added --- project.clj | 3 +- src/notehub/api.clj | 1 + src/notehub/handler.clj | 21 +++++++++-- src/notehub/storage.clj | 7 ++-- src/notehub/views.clj | 3 +- test/notehub/test/storage.clj | 71 ++++++++++++++++++----------------- 6 files changed, 63 insertions(+), 43 deletions(-) diff --git a/project.clj b/project.clj index 2d10511..194d447 100644 --- a/project.clj +++ b/project.clj @@ -1,6 +1,7 @@ (defproject NoteHub "2.0.0" :description "A free and anonymous hosting for markdown pages." - :dependencies [[org.clojure/clojure "1.5.1"] + :dependencies [[org.clojure/clojure "1.6.0"] + [org.clojure/core.cache "0.6.3"] [hiccup "1.0.0"] [zeus "0.1.0"] [iokv "0.1.1"] diff --git a/src/notehub/api.clj b/src/notehub/api.clj index a8b3be2..7a426dd 100644 --- a/src/notehub/api.clj +++ b/src/notehub/api.clj @@ -87,6 +87,7 @@ (defn get-note [{:keys [noteID]}] (if (storage/note-exists? noteID) (let [note (storage/get-note noteID)] + (storage/increment-note-view noteID) {:note note :title (derive-title note) :longURL (get-path noteID) diff --git a/src/notehub/handler.clj b/src/notehub/handler.clj index ab6904d..b5297bb 100644 --- a/src/notehub/handler.clj +++ b/src/notehub/handler.clj @@ -6,6 +6,7 @@ [clojure.string :rename {replace sreplace} :only [replace]] [clojure.core.incubator :only [-?>]]) (:require + [clojure.core.cache :as cache] [hiccup.util :as util] [compojure.handler :as handler] [compojure.route :as route] @@ -13,6 +14,9 @@ [notehub.storage :as storage] [cheshire.core :refer :all])) +; note page cache +(def C (atom (cache/lru-cache-factory {}))) + ; TODO: make sure the status is really set to the response!!!! (defn- response "Sets a custom message for each needed HTTP status. @@ -56,7 +60,10 @@ (return-content-type "text/plain; charset=utf-8" md-text))) (GET "/:year/:month/:day/:title/stats" [year month day title] - (when-let [resp (api/get-note {:noteID (api/build-key year month day title)})] + (let [note-id (api/build-key year month day title) + resp {:statistics (storage/get-note-statistics note-id) + :note (storage/get-note note-id) + :noteID note-id}] (statistics-page resp))) (GET "/:year/:month/:day/:title/edit" [year month day title] @@ -69,7 +76,13 @@ :year year :month month :day day :title title) note-id (api/build-key year month day title)] (when (storage/note-exists? note-id) - (note-page note-id (storage/create-short-url note-id params))))) + (if (cache/has? @C note-id) + (do + (swap! C cache/hit note-id) + (storage/increment-note-view note-id)) + (swap! C cache/miss note-id + (note-page note-id (storage/create-short-url note-id params)))) + (cache/lookup @C note-id)))) (GET "/:short-url" [short-url] (when-let [params (storage/resolve-url short-url)] @@ -103,7 +116,9 @@ :signature (storage/sign pid psk noteID note password)))] (if (get-in resp [:status :success]) - (redirect (:longURL resp)) + (do + (swap! C cache/evict noteID) + (redirect (:longURL resp))) (response 403))) (response 500)))) diff --git a/src/notehub/storage.clj b/src/notehub/storage.clj index 82e81d4..dced2c1 100644 --- a/src/notehub/storage.clj +++ b/src/notehub/storage.clj @@ -80,9 +80,10 @@ (defn get-note [noteID] (when (note-exists? noteID) - (do - (redis :hincrby :views noteID 1) - (unzip (redis :hget :note noteID))))) + (unzip (redis :hget :note noteID)))) + +(defn increment-note-view [noteID] + (redis :hincrby :views noteID 1)) (defn short-url-exists? [url] (= 1 (redis :hexists :short-url url))) diff --git a/src/notehub/views.clj b/src/notehub/views.clj index 893f8c6..1c07139 100644 --- a/src/notehub/views.clj +++ b/src/notehub/views.clj @@ -8,7 +8,8 @@ [hiccup.element] [hiccup.util :only [escape-html]] [hiccup.page :only [include-js html5]]) - (:require [notehub.api :as api])) + (:require + [notehub.api :as api])) (def get-message (get-map "messages")) diff --git a/test/notehub/test/storage.clj b/test/notehub/test/storage.clj index 4456178..003af4d 100644 --- a/test/notehub/test/storage.clj +++ b/test/notehub/test/storage.clj @@ -32,38 +32,39 @@ (is (= metadata (resolve-url url))) (delete-short-url url) (is (not (short-url-exists? url)))))) - (testing "of correct note creation" - (is (= (do - (add-note (build-key date test-title) test-note "testPID") - (is (= 2 (redis :scard (str (build-key date test-title) :urls)))) - (create-short-url (build-key date test-title) metadata) - (is (= 3 (redis :scard (str (build-key date test-title) :urls)))) - (get-note (build-key date test-title))) - test-note)) - (is (= "1" (get-note-views (build-key date test-title)))) - (is (= (do - (get-note (build-key date test-title)) - (get-note-views (build-key date test-title))) - "2"))) - (testing "of note update" - (is (= (do - (add-note (build-key date test-title) test-note "testPID" "12345qwert") - (get-note (build-key date test-title))) - test-note)) - (is (valid-password? (build-key date test-title) "12345qwert")) - (is (= (do - (edit-note (build-key date test-title) "update") - (get-note (build-key date test-title))) - "update"))) - (testing "of the note access" - (is (not= (get-note (build-key date test-title)) "any text"))) - (testing "of note existence" - (is (note-exists? (build-key date test-title))) - (is (short-url-exists? test-short-url)) - (is (= 3 (redis :scard (str (build-key date test-title) :urls)))) - (delete-note (build-key date test-title)) - (is (not (short-url-exists? test-short-url))) - (is (not (note-exists? (build-key date test-title)))) - (is (= 0 (redis :scard (str (build-key date test-title) :urls)))) - (is (not (note-exists? (build-key [2013 06 03] test-title)))) - (is (not (note-exists? (build-key date "some title")))))) + (testing "of correct note creation" + (is (= (let [note-id (build-key date test-title)] + (add-note note-id test-note "testPID") + (is (= 2 (redis :scard (str note-id :urls)))) + (create-short-url note-id metadata) + (is (= 3 (redis :scard (str note-id :urls)))) + (increment-note-view note-id) + (get-note note-id)) + test-note)) + (is (= "1" (get-note-views (build-key date test-title)))) + (is (= (do + (increment-note-view (build-key date test-title)) + (get-note-views (build-key date test-title))) + "2"))) + (testing "of note update" + (is (= (do + (add-note (build-key date test-title) test-note "testPID" "12345qwert") + (get-note (build-key date test-title))) + test-note)) + (is (valid-password? (build-key date test-title) "12345qwert")) + (is (= (do + (edit-note (build-key date test-title) "update") + (get-note (build-key date test-title))) + "update"))) + (testing "of the note access" + (is (not= (get-note (build-key date test-title)) "any text"))) + (testing "of note existence" + (is (note-exists? (build-key date test-title))) + (is (short-url-exists? test-short-url)) + (is (= 3 (redis :scard (str (build-key date test-title) :urls)))) + (delete-note (build-key date test-title)) + (is (not (short-url-exists? test-short-url))) + (is (not (note-exists? (build-key date test-title)))) + (is (= 0 (redis :scard (str (build-key date test-title) :urls)))) + (is (not (note-exists? (build-key [2013 06 03] test-title)))) + (is (not (note-exists? (build-key date "some title"))))))