简体   繁体   English

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

[英]Stack overflow exception in compojure web project

I've been playing around with clojure and have been using it to build a simple little audio player. 我一直在玩clojure,并一直使用它来构建一个简单的小音频播放器。 The strange thing is that sometimes, maybe one out of twenty, when contacting the server I will get the following error: 奇怪的是,有时联系服务器时,可能会十分之一,出现以下错误:

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)
        ...

If I do it right after again it always works. 如果我一次又一次这样做,它将始终有效。 So it appears to be related to timing or something. 因此,它似乎与时机或某些东西有关。 The code in question is: 有问题的代码是:

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

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

and

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

where coll is extracted from this function: 从此函数中提取coll的位置:

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

which uses: 使用:

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

it gets called more or less directly from the request I get in: 它或多或少直接从我收到的请求中被调用:

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

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

I never get the handling command in my log, so it must die when it does the tracks-by-album. 我从来没有在日志中得到处理命令,因此当它按专辑进行录制时,它必须死掉。

so it does appear to be the tracks-by-album function from the stack trace. 因此它看起来确实是堆栈跟踪中的逐专辑功能。 I just don't see why it sometimes works and sometimes doesn't. 我只是不明白为什么它有时起作用而有时却不起作用。 I say that it's tracks-by-album because it's the only function (including it's children) that does filter, as can be seen in the trace. 我说这是按专辑跟踪的,因为它是唯一可以过滤的功能(包括它的子功能),可以在跟踪中看到。

All the source code is available at: http://code.google.com/p/mucomp/ . 所有源代码都可以通过以下网址获得: http : //code.google.com/p/mucomp/ It's my little hobby project to learn clojure and so far it's quite buggy (this is just one bug :)) so I havn't really liked to tell too many people about it yet :) 这是我学习clojure的一个小爱好项目,到目前为止,它是相当多的错误(这只是一个错误:)),所以我还不太喜欢告诉太多的人:)

I asked the question on the clojure mailing list. 我在clojure邮件列表上问了这个问题。 And it appears that the answer is that filter returns a lazy seq, and when you chain those, you'll end in a stack overflow at some point. 看来答案是过滤器返回了一个惰性序列,当您链接这些序列时,有时会在堆栈溢出中结束。 One can force the generation of the sequence using doall. 可以使用doall强制生成序列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM