clojure/ring/jetty: я использую сервер lein ring. Как настроить экземпляр причала, который будет создан?

Когда я напрямую вызывал обработчик причала, я смог передать конфигуратор следующим образом:

(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)))}))

Мне пришлось сделать это, потому что я продолжал получать ошибку FULL HEAD при публикации. Теперь я провел рефакторинг, чтобы напрямую использовать > сервер lein ring, который вызывается из командной строки.

> lein ring server

Это использует некоторую конфигурацию, указанную в моем проекте.clj:

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

Это прекрасно работает, но теперь я снова получаю проблему FULL HEAD. Поэтому я попытался добавить туда конфигуратор:

: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})

И это не удается с этой трассировкой стека:

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)

Я решил, что это связано с размещением функции непосредственно на карте, поэтому я определил ее вне проекта (в caribou.api.core) и попытался ссылаться на нее, как и на остальные функции, определенные в другом месте:

;; 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})

Это раскручивает приложение, но я все равно получаю ошибку 413: FULL HEAD при публикации. Любые идеи? Спасибо!


person prismofeverything    schedule 23.04.2012    source источник


Ответы (2)


Вещи, написанные внутри формы defproject, по умолчанию не оцениваются, но вы можете использовать ~ (без кавычек) в defproject, когда вам это нужно:

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

В этой конкретной ситуации вы должны убрать из кавычек форму fn, определяющую вашу функцию конфигуратора (которая без снятия кавычек используется как список, содержащий набор символов, а не компилируется в функцию).

В качестве альтернативы вы можете определить конфигуратор вне формы defproject и сослаться на его имя внутри defproject, как в вашем втором подходе, но тогда вам нужно убрать имя внутри defproject из кавычек, иначе оно будет рассматриваться как символ. NB. в последнем случае исключение не создается, потому что символы на самом деле вызываются и принимают произвольные аргументы (но всегда возвращают nil только при вызове с чем-то, кроме карты или набора; с картами или наборами они ищут себя в своих аргументах) .

person Michał Marczyk    schedule 25.04.2012
comment
Это, вероятно, что-то, что изменилось с тех пор, как ответ был опубликован, но когда мне нравится предложенное здесь (без кавычек определение функции), я получаю еще одну ошибку: нет функции чтения для объекта тега. У вас есть идеи, почему это может произойти? - person Timur; 15.10.2015

Ответ заключается в том, чтобы не использовать кольцевой сервер, а просто запустить пристань напрямую с кольцом/кольцевым причалом-адаптером. Таким образом, я все еще могу перейти в конфигуратор, который, кстати, изменился на это:

(defn full-head-avoidance
  [jetty]
  (doseq [connector (.getConnectors jetty)]
    (.setRequestHeaderSize connector header-buffer-size)))
person prismofeverything    schedule 24.04.2012