Clojure Noir WAR/Servlet的初始化挂钩(CloudFoundry)

kan*_*aka 5 java clojure war leiningen

我正在构建一个Clojure Noir Web应用程序,以便在CloudFoundry中作为WAR文件运行.

在我的project.clj中,我有:

:ring {:handler appname.server/handler}
Run Code Online (Sandbox Code Playgroud)

在server.clj中,我使用Noir创建一个处理程序:

(def handler (noir.server/gen-handler {:ns 'appname}))
Run Code Online (Sandbox Code Playgroud)

我使用lein ring插件构建WAR文件:

lein ring uberwar
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令推送到CloudFoundry:

vmc push appname
Run Code Online (Sandbox Code Playgroud)

请求处理程序工作正常,我可以浏览到应用程序的URL就好了.

所以问题是:在应用程序启动时进行初始化的正确方法是什么?

我可以在server.clj中执行以下操作:

(when (System/getenv "VCAP_APPLICATION")
  (init-func))
Run Code Online (Sandbox Code Playgroud)

但是有一些问题.首先,似乎是在错误的时间进行初始化(当读取/评估代码而不是在应用程序启动时).其次,保护器特定于CloudFoundry,我确定有一个适当的一般WAR方式来做到这一点.

我认为这是ServletContextListener上contextInitialized方法的目的但是如何用Noir/ring挂钩呢?

kan*_*aka 6

通过查看WAR处理的环源来计算出来

project.clj:ring map采用:init关键字,如下所示:

:ring {:init appname.server/my-init
       :handler appname.server/handler}
Run Code Online (Sandbox Code Playgroud)

将在应用程序启动时调用my-init函数.

警告:这显然会增加应用程序初始启动所需的内存量.没有初始化,128M就足够了.使用初始化代码,应用程序启动失败,因此我不得不将内存增加到256M.我怀疑使用init代码时,JVM在编译/执行Clojure代码之前没有时间进行垃圾收集.