compojure web项目中的堆栈溢出异常

时间:2010-04-30 22:39:13

标签: web-applications clojure compojure

我一直在玩clojure,并一直用它来构建一个简单的小型音频播放器。奇怪的是,有时,也许有二十分之一,当联系服务器时,我会收到以下错误:

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 :(得分:1)

我在clojure邮件列表上问了一个问题。似乎答案是过滤器返回一个懒惰的seq,当你链接它们时,你会在某个时刻以堆栈溢出结束。可以使用doall强制生成序列。