J'ai joué avec clojure et je l'ai utilisé pour créer un petit lecteur audio simple. La chose étrange est que, parfois, peut-être un sur vingt, pour contacter le serveur j'obtenir l'erreur suivante:Exception de dépassement de pile dans le projet web de 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)
...
Si je le fais juste après encore, il fonctionne toujours. Donc, il semble être lié à un moment ou quelque chose. Le code en question est:
(defn add-track [t]
(common/ref-add tracks t))
(defn add-collection [coll]
(doseq [track coll] (add-track track)))
et
(defn ref-add [ref value]
(dosync (ref-set ref (conj @ref value))))
où coll est extrait de cette fonction:
(defn tracks-by-album [album]
(sort sort-tracks (filter #(= (:album %) album) @tracks)))
qui utilise:
(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)))))
il est appelé plus ou moins directement de la demande Je reçois dans:
(when-handle-command cmd params (audio/tracks-by-album decoded-name))
(defn when-handle-command [cmd params data]
(println (str "handling command:" cmd))
....)
Je ne reçois jamais la commande de manipulation dans mon journal, il faut mourir quand il fait les pistes-en-album. Par conséquent, il semble que ce soit la fonction pistes par album de la trace de la pile. Je ne vois tout simplement pas pourquoi cela fonctionne parfois et parfois non. Je dis que c'est une chanson par album parce que c'est la seule fonction (y compris les enfants) qui filtre, comme on peut le voir dans la trace. Tous les codes sources sont disponibles à l'adresse: http://code.google.com/p/mucomp/. C'est mon petit projet de loisir d'apprendre le clojure et jusqu'à présent c'est assez bogué (c'est juste un bug :)) donc je n'ai pas vraiment aimé en dire trop à ce sujet :)
Vous dites "(...) il semble donc que ce soit la fonction pistes par album de la trace de pile", mais cette fonction n'apparaît pas dans (la partie de) la trace de pile que vous avez publiée. Y a-t-il plus de sortie d'erreur? De plus, pourriez-vous nous montrer des pistes de tri et des endroits où des titres par album sont appelés? (Ou peut-être que vous pourriez choisir ceux qui semblent les plus pertinents s'il y en a trop pour les poster tous.) –
J'ai mis à jour le poste avec un peu plus de code. La trace de la pile continue aussi comme l'extrait que j'ai posté. Il n'y a pas d'information plus tristement intéressante ;-) –
encore une chose je voudrais ajouter est que les pistes est un ref à une liste d'environ 2300 éléments (structs avec des choses comme le nom, le nom de fichier, etc.) –