2012-02-01 24 views
5

Tôi đang tạo ứng dụng web Clojure Noir để chạy dưới dạng tệp WAR trong CloudFoundry.Móc khởi tạo cho Clojure Noir WAR/Servlet (CloudFoundry)

Trong project.clj của tôi, tôi có:

:ring {:handler appname.server/handler} 

Trong server.clj tôi tạo một handler sử dụng Noir:

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

tôi xây dựng các tập tin WAR sử dụng một plugin vòng Lein:

lein ring uberwar 

Sau đó, chuyển sang CloudFoundry bằng cách sử dụng:

vmc push appname 

Trình xử lý yêu cầu hoạt động tốt và tôi có thể duyệt đến URL của ứng dụng tốt.

Vì vậy, câu hỏi đặt ra là: cách chính xác để khởi tạo khi ứng dụng được bắt đầu là gì?

tôi có thể làm như sau trong server.clj:

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

Nhưng có một vài vấn đề với điều đó. Đầu tiên, có vẻ như đó là làm việc khởi tạo vào thời điểm sai (khi mã được đọc/đánh giá thay vì khởi động ứng dụng). Thứ hai, bảo vệ là cụ thể cho CloudFoundry và tôi chắc chắn có một cách thức WAR hợp lý để làm điều này.

Tôi nghĩ rằng đây là mục đích của phương thức contextInitialized trên ServletContextListener nhưng làm thế nào để móc nối với Noir/ring?

Trả lời

6

đặn nó ra bằng cách nhìn vào ring source for WAR handling

Các project.clj: bản đồ vòng mất một: từ khóa init như vậy:

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

Chức năng my-init sẽ được gọi khi khởi động ứng dụng.

Caveat: điều này rõ ràng sẽ làm tăng lượng bộ nhớ cần thiết cho ứng dụng để khởi động ban đầu. 128M là đủ mà không cần khởi tạo. Với mã khởi tạo, khởi động ứng dụng không thành công, vì vậy tôi phải tăng bộ nhớ lên 256M. Tôi nghi ngờ rằng với mã init JVM không có thời gian để thu thập rác trước khi mã Clojure được biên dịch/thực thi.

Các vấn đề liên quan