taoensso / nippy

The fastest serialization library for Clojure
https://www.taoensso.com/nippy
Eclipse Public License 1.0
1.04k stars 60 forks source link

serializable? fails with StackOverwflow on simple 'repeated' list #57

Closed behrica closed 9 years ago

behrica commented 9 years ago

I had a simple data structure (list of list of strings) and noticed that the function serializable? fails with StackOverFlow, but I can successfully call "freeze" on it.

The simplest case which breaks seems to be this:

(require 'taoensso.nippy.utils)
(def l (list 1))
(def ll (repeat 2 l))
(taoensso.nippy.utils/serializable? ll)  -> StackOverwlow

(if I use "(def ll (list l l)" is does work ....) So it is somehow related to structural sharing of clojure ?

My use case is to make a function to freeze/serialize a bunch of vars , where some of them might not be serializable. So I want to "test" this before calling "freeze" on it.

ptaoussanis commented 9 years ago

Hi Behrica, I can't reproduce this - I get (serializable? ll) => true as expected.

Does this continue to happen after rebooting your Clojure REPL? If so, please provide some more details from your environment: Nippy version, Clojure version, JVM, JVM opts (as in project.clj), OS, etc.

Thanks, cheers! :-)

behrica commented 9 years ago

I tried a bit and it seems to depend on which repl i am using.... I saw it first by using, the Gorilla repl, and there I can still reproduce it. https://github.com/JonyEpsilon/gorilla-repl

So adding the above code into an fresh gorilla repl, makes it fail. image

The gorilla repl does some leiningen injection magic and custom rendering , maybe its related.

I saw it as well inside the Cider repl in Emacs, because I remember the long stacktrace, (but cannot reproduce it anymore ...)

So in a "pure leiningen repl", inside the same project, I never saw it. I tried now, and it works.

In the meanwhile I changed my code and instead of checking for serializable?, I just call "freeze" and catch all exceptions. So I will not see it anymore...

behrica commented 9 years ago

Not sure any more, if its really Gorilla... It is the "repeated" function which screws things up. I get this three cases:

(taoensso.nippy.utils/serializable? (list (list 1) (list 1)))   ;working
(def l (list 1)) (taoensso.nippy.utils/serializable? (list l l))  ;working
(taoensso.nippy.utils/serializable? (repeat 2 l))   ;not working

But in emacs Cider they all three work....

JonyEpsilon commented 9 years ago

The only thing I can think of here that is different between Gorilla and CIDER is that Gorilla will call its render function on the result. This can, for instance, realise a lazy sequence which might not be realised by the code itself. I wouldn't have thought would happen here, though, as your intermediate results in the first example are defed (so the renderer renders the var, not the value). And the latest failure case is a single line, so should be unaffected. I'll try and reproduce when I have a chance and let you know if I find anything.

ptaoussanis commented 9 years ago

Yeah, sorry - I'm not at all familiar with Gorilla. Will leave this issue open for now, but unless we can find a reproducible case that shows in the standard REPL - I do believe it seems likeliest that the cause isn't with Nippy (sorry).

One way to check might be trying a simplified case: try to realise the same ll form without Nippy's involvement. I.e. check what happens with:

(def l (list 1))
(def ll (repeat 2 l))
(doall ll)

If that works, then I'd try looking at possible issues with writeObject/readObject and Gorilla interactions.

Good luck, cheers! :-)

ptaoussanis commented 9 years ago

Closing this for now. Please feel free to reopen if you identify an issue with Nippy specifically. Good luck, cheers! :-)

JonyEpsilon commented 9 years ago

Hi Peter, I haven't had a chance to look at this yet, but the Gorilla issue is still open, so I will get to it some day! I'll come back here if it turns up anything of interest regarding Nippy.

ptaoussanis commented 9 years ago

Thanks Jony, no problem. Cheers :-)