Skip to content

Instantly share code, notes, and snippets.

@robert-stuttaford
Created July 3, 2013 11:33
Show Gist options
  • Save robert-stuttaford/5917189 to your computer and use it in GitHub Desktop.
Save robert-stuttaford/5917189 to your computer and use it in GitHub Desktop.
using database functions to avoid race conditions between multiple webservers
(defn start-session!
[]
;; put-value! talks to ring's sessions dsl
(put-value! :session-uuid (db/new-uuid)))
(defn uuid
[]
;; get-value talks to ring's sessions dsl
(get-value :session-uuid))
(defn has-session?
[]
(boolean (uuid)))
(def create-session
#db/fn {:lang :clojure
:params [db id uuid remote-address user-agent user-id]
:code (if-let [session (when-not (seq (d/q '[:find ?e :in $ ?uuid :where
[?e :meta/type :meta.type/session]
[?e :meta/uuid ?uuid]]
db uuid))
{:db/id id
:meta/uuid uuid
:meta/type :meta.type/session
:session/remote-address remote-address
:session/user-agent user-agent
:meta/user user-id})]
[session]
(throw (ex-info "Create session failed"
{:meta/uuid ["Already exists"]})))})
;; to be called whenever create-session changes
(defn install-db-fns!
[]
(db/transact! [{:db/id (db/new-id)
:db/ident :session/create-session
:db/fn create-session}]))
(defn save-session!
[user]
(when-not (has-session?)
(start-session!))
(db/transact! [[:session/create-session
(db/new-id)
(uuid)
(or (:remote-addr request/*request*) "n/a")
(or (get (:headers request/*request*) "user-agent") "n/a")
(db/id user)]]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment