Хук инициализации для Clojure Noir WAR / Servlet (CloudFoundry) - PullRequest
5 голосов
/ 02 февраля 2012

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

В моем project.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/ кольцо?

1 Ответ

6 голосов
/ 02 февраля 2012

Понял это, посмотрев на источник сигнала для обработки WAR

Project.clj: кольцо карты принимает ключевое слово: init, например:

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

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

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

...