2012-02-01 13 views
5

Buduję aplikację internetową Clojure Noir, która działa jako plik WAR w CloudFoundry.Hook inicjujący dla Clojure Noir WAR/Servlet (CloudFoundry)

W moim project.clj mam:

:ring {:handler appname.server/handler} 

W server.clj tworzę obsługi przy użyciu Noir:

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

zbudować plik WAR przy użyciu wtyczki pierścień Lein:

lein ring uberwar 

Następnie naciśnij do CloudFoundry, używając:

vmc push appname 

Obsługa żądań działa dobrze i mogę przejrzeć adres URL aplikacji.

Pytanie brzmi: jaki jest właściwy sposób inicjowania przy uruchamianiu aplikacji?

mogę wykonać następujące czynności w server.clj:

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

Ale istnieje kilka problemów z tym. Po pierwsze, wygląda na to, że robi inicjalizację w nieodpowiednim momencie (kiedy kod jest czytany/eval, a nie na początku aplikacji). Po drugie, obrońca jest specyficzny dla CloudFoundry i jestem pewien, że istnieje odpowiednia ogólna metoda WAR, aby to zrobić.

Myślę, że jest to celem metody contextInitialized w ServletContextListener, ale jak mam to podłączyć z Noir/ring?

Odpowiedz

6

Zdobione patrząc na ring source for WAR handling

The project.clj: pierścień map odbywa an: startowego słowa kluczowego tak:

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

Funkcja My-startowych zostanie wywołana przy starcie aplikacji.

Zastrzeżenie: to najwyraźniej balansuje ilość pamięci potrzebnej aplikacji do pierwszego uruchomienia. 128M było wystarczające bez inicjalizacji. Po uruchomieniu kodu inicjowanie aplikacji nie powiodło się, więc musiałem podbić pamięć do 256M. Podejrzewam, że z kodem init JVM nie ma czasu na zbieranie śmieci zanim kod Clojure zostanie skompilowany/wykonany.