2

私はclojureで遊んでいて、それを使ってシンプルな小さなオーディオプレーヤーを構築してきました。奇妙なことに、サーバーに接続するときに、おそらく20分の1の場合、次のエラーが発生します。

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つのバグです:))ので、まだあまり多くの人にそれについて話すのは好きではありません:)

4

1 に答える 1

1

clojureメーリングリストで質問しました。そして答えは、フィルターが怠惰なシーケンスを返すということであるように見えます、そしてそれらを連鎖させるとき、あなたはある時点でスタックオーバーフローで終わるでしょう。doallを使用してシーケンスの生成を強制することができます。

于 2010-05-03T19:25:26.677 に答える