在Heroku的Compojure应用程序中放置monger连接的位置?

时间:2013-09-13 21:33:33

标签: heroku clojure compojure monger

我使用带有lein 2.0的lein new compojure mongotest和一个Procfile web: lein ring server-headless $PORT创建了一个compojure应用程序。这工作正常,但现在我添加

(def mongolab-url (System/getenv "MONGOLAB_URI"))
(println "mongolab-url")
(println mongolab-url)
(mg/connect-via-uri! mongolab-url)

当我尝试git push heroku master Heroku最终给了我

   Compiling mongotest.handler
   mongolab-url
   nil
   Exception in thread "main" java.lang.NullPointerException, compiling:(handler.clj:13:1)
    ... 25 more
   Compilation failed: Subprocess failed
   Error encountered performing task 'compile' with profile(s): 'production'
   Suppressed exit
!  Failed to build.
!  Push rejected, failed to compile Clojure (Leiningen 2) app

我在handler.clj的顶层添加了这些行。我看到连接的一些旧文档是在main中创建的,但这必须是旧版本的compojure,因为在生成的应用程序中不再有main(我已经找到)。在当前版本中应该在哪里建立连接? (或者我的Procfile不对吗?)

(是的,MONGOLAB_URI中定义了heroku config

2 个答案:

答案 0 :(得分:1)

对我有用且似乎最惯用的答案是将上述连接放入同一文件中的函数initmyproject/handler.clj

(defn init[] (mg/connect-via-uri! (System/getenv "MONGOLAB_URI")))

并从

更新project.clj文件环描述符行
:ring {:handler myproject.handler/app}

:ring {:handler myproject.handler/app :init myproject.handler/init}

答案 1 :(得分:0)

您不希望在命名空间加载时发生副作用(例如打开数据库连接),这是有效的编译时间。当你在clojure启动时编译你的代码时,通常你可以逃避这些事情,但在这种情况下,heroku会将你的应用程序预编译到一个jar中,以便它可以更快地提供它。现在,在编译时,您尝试阅读PORT环境变量;但是直到heroku试图实际运行你的应用程序才会设置它。

解决方案是仅在运行时创建它,例如在-main或其他函数中创建它,或者将其定义为只delay的{​​{1}}运行时。