2010-04-30 3 views
1

Я играл с clojure и использовал его для создания простого аудио-плеера. Странно то, что иногда, может быть, один из двадцати, при обращении к серверу я получаю следующее сообщение об ошибке:Исключение переполнения стека в веб-проекте compojure

2010-04-20 15:33:20.963::WARN: Error for /control 
java.lang.StackOverflowError 
    at clojure.lang.RT.seq(RT.java:440) 
    at clojure.core$seq__4245.invoke(core.clj:105) 
    at clojure.core$filter__5084$fn__5086.invoke(core.clj:1794) 
    at clojure.lang.LazySeq.sval(LazySeq.java:42) 
    at clojure.lang.LazySeq.seq(LazySeq.java:56) 
    at clojure.lang.RT.seq(RT.java:440) 
    at clojure.core$seq__4245.invoke(core.clj:105) 
    at clojure.core$filter__5084$fn__5086.invoke(core.clj:1794) 
    at clojure.lang.LazySeq.sval(LazySeq.java:42) 
    at clojure.lang.LazySeq.seq(LazySeq.java:56) 
    at clojure.lang.RT.seq(RT.java:440) 
    at clojure.core$seq__4245.invoke(core.clj:105) 
    at clojure.core$filter__5084$fn__5086.invoke(core.clj:1794) 
    at clojure.lang.LazySeq.sval(LazySeq.java:42) 
    at clojure.lang.LazySeq.seq(LazySeq.java:56) 
    at clojure.lang.RT.seq(RT.java:440) 
    at clojure.core$seq__4245.invoke(core.clj:105) 
    at clojure.core$filter__5084$fn__5086.invoke(core.clj:1794) 
    at clojure.lang.LazySeq.sval(LazySeq.java:42) 
    at clojure.lang.LazySeq.seq(LazySeq.java:56) 
    at clojure.lang.RT.seq(RT.java:440) 
     ... 

Если я это сделать сразу после снова он всегда работает. Таким образом, похоже, это связано с временем или чем-то. Код в вопросе:

(defn add-track [t] 
    (common/ref-add tracks t)) 

(defn add-collection [coll] 
    (doseq [track coll] (add-track track))) 

и

(defn ref-add [ref value] 
    (dosync (ref-set ref (conj @ref value)))) 

где Coll извлекается из этой функции:

(defn tracks-by-album [album] 
    (sort sort-tracks (filter #(= (:album %) album) @tracks))) 

, который использует:

(defn get-album-from-track [track] 
    (seq/find-first #(= (:album track) (:name %)) @albums)) 

(defn sort-tracks [track1 track2] 
    (cond (= (:album track1) (:album track2)) 
    (cond (and (:album-track track1) (:album-track track2)) 
     (< (:album-track track1) (:album-track track2)) 
     :else 0) 
    :else 
    (> (:year (get-album-from-track track1)) (:year (get-album-from-track track2))))) 

он вызывается более или менее непосредственно из запроса Я получаю в:

(when-handle-command cmd params (audio/tracks-by-album decoded-name)) 

(defn when-handle-command [cmd params data] 
    (println (str "handling command:" cmd)) 
    ....) 

Я никогда не получаю команду обработки в моем журнале, так что он должен умереть, когда он делает треки-от-альбома.

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

Весь исходный код доступен по адресу: http://code.google.com/p/mucomp/. Это мой маленький проект по хобби, который выучил clojure, и пока он довольно глючный (это всего лишь одна ошибка :)), поэтому мне не нравилось рассказывать об этом слишком много людей :)

+1

Вы говорите «(...), чтобы он выглядел как функция« следы по альбому »из трассировки стека», но эта функция не содержит (часть) трассировки стека, которую вы опубликовали. Было ли больше ошибок? Кроме того, вы могли бы показать нам сортировку и любые дорожки из-за альбома? (Или, может быть, вы могли бы выбрать те, которые кажутся наиболее актуальными, если их слишком много, чтобы опубликовать их все.) –

+0

Я обновил сообщение с помощью некоторого кода. Также трассировка стека продолжается так же, как и этот фрагмент, который я опубликовал. Нет более интересной информации, к сожалению ;-) –

+0

еще одна вещь, которую я хотел бы добавить, состоит в том, что треки - это ссылка на список из примерно 2300 элементов (структуры с такими именами, как имя, имя файла и т. Д.) –

ответ

1

Я задал вопрос о список рассылки clojure. И кажется, что ответ заключается в том, что фильтр возвращает ленивый seq, и когда вы их связываете, вы в какой-то момент закончите переполнение стека. Можно заставить генерировать последовательность, используя doall.

Смежные вопросы