<< Back to previous view

[CMEMOIZE-12] NPE with memoize/ttl Created: 05/Dec/13  Updated: 06/Nov/15  Resolved: 06/Nov/15

Status: Closed
Project: core.memoize
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Scott Morgan Assignee: Fogus
Resolution: Not Reproducible Votes: 1
Labels: bug

org.clojure/core.memoize "0.5.6"


I'm trying still trying to reproduce it, but I noted this in my logs if my compojure app on a subsequent request to the memoized function.

at clojure.core.memoize$through_STAR_$fn_401$fn_402.invoke(memoize.clj:53)
at clojure.lang.Delay.deref(Delay.java:33)
at clojure.core$deref.invoke(core.clj:2128)
at clojure.core.memoize$build_memoizer$fn__456.doInvoke(memoize.clj:140)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
at clojure.lang.RestFn.invoke(RestFn.java:436)

Comment by Aaron Iba [ 19/Feb/14 4:49 PM ]

I have the same exact stack trace / line numbers in my logs. I have no idea how to reproduce. I would love to get advice on how to debug this.

In my case, this is running in a web app (ring) context.

Comment by Nicola Mometto [ 19/Feb/14 6:13 PM ]

I noticed that core.memoize throws an NPE if the function memoized throws an exception.
I don't know if this is what you're running into but it might be something to look into.

Comment by Steve Losh [ 04/Jun/14 3:21 PM ]

We're seeing this too. To reproduce:

(require '[clojure.core.memoize :as memo])

(defn f []
  (/ 1 0))

(def m (memo/ttl f :ttl/threshold 5000))

If you call (m) the first time, you get a divide by zero exception as expected. If you call it again you'll get an NPE until the TTL expires (in 5 seconds in this case) at which point you'll get one correct error and then more NPEs.

Comment by Steve Losh [ 05/Jun/14 12:04 PM ]

Note that if you update to Clojure 1.6 the NPEs go away, but the memoizer caches the exception as the result of the function. This is fine for pure functions but not for what we need, so we just wrote a wrapper around memoize/ttl to catch exceptions and evict the cache before rethrowing them. It's ugly but it works good enough.

Comment by Alex Miller [ 06/Nov/15 11:04 AM ]

The change in behavior with 1.6 was due to the implementation of delay changing in 1.6 to rethrow exceptions repeatably.

However, core.memoize has changed since 0.5.7 to use an internal (re-trying) version of d-lay.

I am going to mark this NR but would appreciate re-opening or a new report with a reproducible case on the latest version if you see it.

Generated at Mon Nov 30 05:48:00 CST 2015 using JIRA 4.4#649-r158309.