1

I'm learning Clojure (1.10) and am writing a small web app using the Luminus framework (3.93), using the Monger client (3.1.0) to connect to a MongoDB instance. Luminus generates some scaffolding code that is to create the database connection pool (using the function monger.core/connect-via-uri) on startup in <myproject>.db.core:

(ns myproject.db.core
  (:require [monger.core :as mg] ... ))

(defstate db*
  :start (-> env :database-url mg/connect-via-uri)
  :stop (-> db* :conn mg/disconnect))

...

My problem: if the MongoDB instance is not available at this point, nothing is shown to warn of the problem. Web pages are served, until one requires a call to a Monger function. At this point the app "churns" and then timeouts (set at 30s) with an exception/stacktrace error screen (which, besides being a horrible user experience, may also expose code/data that is supposed to remain secret).

How can I best guard against starting up the application when the prerequisite database is not available?

One (admittedly clumsy) initial attempt is to insert a Monger call into the above startup code. This causes a timeout exception during startup (with an exception message), instead of starting up the web app. What is a better way?

Also, do you know of a way to let a problem like this halt the startup process instead of retrying and churning out failure messages?

(defstate db*
  :start (-> env :database-url mg/connect-via-uri
             ; clumsy way to catch timeouts due to no database when starting up:
             (#(mg/get-db-names (:conn %)) %))
  :stop (-> db* :conn mg/disconnect))
frIT
  • 3,213
  • 1
  • 18
  • 22

2 Answers2

0

I'm not an expert on Monger, but this guide on their website shows ways of changing the timeout.

So, maybe change the timeout to 3 seconds or something, then see of you can connect. Otherwise, throw and exception or something.

Alan Thompson
  • 29,276
  • 6
  • 41
  • 48
0

you can try to ping the db to check its availability:

(mg/command db {:ping 1})

Moreover, you can create a scheduler (for example here this) to check the db's status periodically

frIT
  • 3,213
  • 1
  • 18
  • 22
Minh Tuan Nguyen
  • 1,026
  • 8
  • 13
  • This doesn't work because the `db` value comes from the `connect-via-uri` call, which retries until timeout and so never reaches the ping. This is also the reason it can't be used anywhere else - need a `db` in the first place to ping it... I guess there may not be a good solution... – frIT Mar 26 '21 at 14:39