2012-04-23 15 views
9

Quando stavo chiamando direttamente il gestore molo, sono stato in grado di passare in un configuratore in questo modo:clojure/ring/jetty: sto usando> lein ring server. Come posso configurare l'istanza di jetty che viene istanziata?

(def header-buffer-size 8388608) 
(defn start [port] 
    (ring/run-jetty 
    (var app) 
    {:port port 
    :join? false 
    :host "127.0.0.1" 
    :configurator 
    (fn [jetty] 
     (doseq [connector (.getConnectors jetty)] 
     (.setHeaderBufferSize connector header-buffer-size)))})) 

ho dovuto fare questo perché ho continuato a ottenere un errore di testa piena durante la pubblicazione. Ora ho effettuato il refactoring delle cose da usare direttamente> lein ring server, che viene chiamato dalla riga di comando.

> lein ring server 

Questo utilizza una certa configurazione specificata nel mio project.clj:

:ring {:handler caribou.api.core/app 
     :servlet-name "caribou-api" 
     :init caribou.api.core/init 
     :port 33443} 

Questa grande opera, ma ora sto ottenendo ancora una volta il problema testa piena. Così ho provato ad aggiungere un configuratore in là:

:ring {:handler caribou.api.core/app 
     :servlet-name "caribou-api" 
     :init caribou.api.core/init 
     :configurator 
     (fn [jetty] 
     (doseq [connector (.getConnectors jetty)] 
      (.setHeaderBufferSize connector 8388608))) 
     :port 33443}) 

E questo viene a mancare con questo stacktrace:

Exception in thread "main" java.lang.ClassCastException: 
clojure.lang.PersistentList cannot be cast to clojure.lang.IFn 
    at ring.adapter.jetty$run_jetty.invoke(jetty.clj:66) 
    at ring.server.standalone$serve$fn__833.invoke(standalone.clj:78) 
    at ring.server.standalone$try_port.invoke(standalone.clj:12) 
    at ring.server.standalone$serve.doInvoke(standalone.clj:75) 
    at clojure.lang.RestFn.invoke(RestFn.java:423) 
    at ring.server.leiningen$serve.invoke(leiningen.clj:20) 

ho pensato che questo aveva a che fare con la messa la funzione direttamente nella mappa del genere, così ho definito al di fuori del progetto (in caribou.api.core) e ha cercato riferimento ad essa come faccio io il resto delle funzioni definite altrove:

;; in caribou/api/core.clj 
(def header-buffer-size 8388608) 
(defn full-head-avoidance 
    [jetty] 
    (doseq [connector (.getConnectors jetty)] 
    (.setHeaderBufferSize connector header-buffer-size))) 

;; in project.clj 
:ring {:handler caribou.api.core/app 
     :servlet-name "caribou-api" 
     :init caribou.api.core/init 
     :configurator caribou.api.core/full-head-avoidance 
     :port 33443}) 

Questo gira l'app, ma ho ancora ottenere il 413: FULL CAPO errore durante la pubblicazione. Qualche idea? Grazie!

risposta

3

roba scritta all'interno di un modulo defproject non viene valutata per impostazione predefinita, ma è possibile utilizzare ~ (unquote) in defproject quando ne avete bisogno a:

(defproject foo "1.2.3" 
    ... 
    :some-fn-key ~(fn [& args] ...)) 

In questa particolare situazione, che ci si unquote forma fn definire la funzione configuratore (che non si toglie la quotatura viene utilizzato come una lista contenente una serie di simboli, piuttosto che compilato in una funzione).

In alternativa, è possibile definire il configuratore di fuori del modulo defproject e fare riferimento al suo nome all'interno defproject come nel tuo secondo approccio, ma poi è necessario unquote il nome all'interno defproject - altrimenti sarà trattata come un simbolo. NB. in quest'ultimo caso non viene prodotta alcuna eccezione, perché i simboli sono in realtà richiamabili e accettano argomenti arbitrari (ma restituiscono sempre e solo nil quando vengono chiamati con qualcosa di diverso da una mappa o da un set; con mappe o insiemi, si presentano nei loro argomenti) .

+0

Probabilmente è qualcosa che è cambiato da quando è stata pubblicata la risposta, ma quando mi piace proporre qui (togliere la definizione della funzione) ottengo un altro errore: "Nessuna funzione di lettura per l'oggetto di tag". Hai un'idea del perché questo potrebbe accadere? – Timur

3

La risposta è di non utilizzare il server dell'anello e di avviare direttamente il molo direttamente con l'adattatore ring/ring-jetty. In questo modo posso ancora passare nel configuratore, che BTW è cambiato a questo:

(defn full-head-avoidance 
    [jetty] 
    (doseq [connector (.getConnectors jetty)] 
    (.setRequestHeaderSize connector header-buffer-size))) 
Problemi correlati