This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-23
Channels
- # admin-announcements (1)
- # arachne (3)
- # aws (1)
- # bangalore-clj (2)
- # beginners (209)
- # boot (81)
- # capetown (2)
- # cider (16)
- # clara (13)
- # cljsjs (16)
- # cljsrn (6)
- # clojure (217)
- # clojure-czech (1)
- # clojure-greece (4)
- # clojure-italy (3)
- # clojure-korea (3)
- # clojure-russia (3)
- # clojure-sg (3)
- # clojure-spec (104)
- # clojure-uk (23)
- # clojurescript (7)
- # component (7)
- # cursive (18)
- # datomic (12)
- # devcards (34)
- # dirac (17)
- # editors (3)
- # emacs (1)
- # events (1)
- # hoplon (62)
- # immutant (12)
- # incanter (1)
- # jobs (1)
- # klipse (2)
- # ldnclj (1)
- # luminus (1)
- # mount (1)
- # off-topic (8)
- # om (50)
- # onyx (46)
- # parinfer (5)
- # pedestal (4)
- # perun (2)
- # reagent (1)
- # rum (1)
- # schema (5)
- # specter (30)
- # untangled (5)
- # vim (46)
I have a database connection object which I’m using as a component, which I can then pass as an argument to database functions, e.g. (db/create conn-component my-thing)
. This works well.
The problem I’m running into is that whenever the connection is interrupted (database unreachable, network problem, etc.), using a database function will result in an exception.
In this situation, the old database connection object becomes useless and I need a new one. How can I use component to solve or avoid this problem?
What you can do is implement a defrecord that participates in the pseudo-protocol that clojure.java.jdbc expects from its db-conn argument
E.g.:
(defrecord DatabasePool [db datasource]
component/Lifecycle
(start [this]
(log/info :msg "Starting database pool")
(let [{:keys [dbtype host port dbname user password]} db]
(when-not (= "postgresql" dbtype)
(throw (ex-info "Unsupported dbtype" {:db db
:dbtype dbtype})))
(let [options (assoc default-database-pool-options
:server-name host
:port-number port
:database-name dbname
:username user
:password password)]
(try
(let [datasource (with-retries* #(hikari/make-datasource options))]
(assoc this :datasource datasource))
(catch Exception e
(log/error :msg "Error creating database pool"
:exception e)
(throw (ex-info "Invalid database pool" {:db db} e)))))))
(stop [this]
(log/info :msg "Stopping database pool")
(when datasource
(hikari/close-datasource datasource))
(assoc this :datasource nil)))