Хук инициализации для Clojure Noir WAR/Servlet (CloudFoundry)

Я создаю веб-приложение Clojure Noir для запуска в виде файла WAR в CloudFoundry.

В моем проекте.clj у меня есть:

:ring {:handler appname.server/handler}

В server.clj я создаю обработчик с помощью Noir:

(def handler (noir.server/gen-handler {:ns 'appname}))

Я создаю файл WAR с помощью плагина lein ring:

lein ring uberwar

Затем нажмите на CloudFoundry, используя:

vmc push appname

Обработчик запросов работает нормально, и я могу просто перейти к URL-адресу приложения.

Итак, вопрос: как правильно выполнить инициализацию при запуске приложения?

Я могу сделать следующее в server.clj:

(when (System/getenv "VCAP_APPLICATION")
  (init-func))

Но есть пара проблем с этим. Во-первых, кажется, что инициализация выполняется в неподходящее время (когда код читается/оценивается, а не при запуске приложения). Во-вторых, протектор специфичен для CloudFoundry, и я уверен, что для этого существует правильный способ WAR.

Я думаю, что это цель метода contextInitialized в ServletContextListener, но как мне подключить его к Noir/ring?


person kanaka    schedule 01.02.2012    source источник


Ответы (1)


Выяснил это, посмотрев источник кольца для обработки WAR

Карта project.clj :ring принимает ключевое слово :init следующим образом:

:ring {:init appname.server/my-init
       :handler appname.server/handler}

Функция my-init будет вызываться при запуске приложения.

Предостережение: очевидно, что это увеличивает объем памяти, необходимый приложению для первоначального запуска. 128M было достаточно без инициализации. С кодом инициализации запуск приложения не удался, поэтому мне пришлось увеличить память до 256M. Я подозреваю, что с кодом инициализации JVM не успевает собирать мусор до того, как код Clojure будет скомпилирован/выполнен.

person kanaka    schedule 02.02.2012