<< Back to previous view

[CMEMOIZE-8] memoizing functions that throw exceptions Created: 09/Jul/13  Updated: 02/Jan/14

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

Type: Defect Priority: Major
Reporter: davie moston Assignee: Fogus
Resolution: Unresolved Votes: 0
Labels: None
Environment:

core.memoize 0.5.6
clojure 1.5.1



 Description   

core.memoize doesn't retry if the orginal function throws an exception.
This is different to clojure.core/memoize, and looks like it's a result of using delays in core.memoize.
I think the core/memoize behaviour makes more sense - if an exception is thrown do not memoize the result, instead retry the function.
Example below.


(ns test-memo.core
(:require [clojure.core.memoize ])
(:import [java.lang.RuntimeException]))

(defn print-and-throw []
(do (println "hi") (throw (RuntimeException.))))

(def normal (memoize print-and-throw))
(def lru (clojure.core.memoize/lru print-and-throw))

user> (test-memo.core/normal)
hi
RuntimeException test-memo.core/print-and-throw (core.clj:6)
user> (test-memo.core/normal)
hi
RuntimeException test-memo.core/print-and-throw (core.clj:6)

(test-memo.core/lru)
hi
RuntimeException test-memo.core/print-and-throw (core.clj:6)
user> (test-memo.core/lru)
NullPointerException clojure.core.memoize/through*/fn-2771/fn-2772 (memoize.clj:53)



 Comments   
Comment by Martin Trojer [ 25/Jul/13 10:31 AM ]

This is caused by the following bug in delay;

http://dev.clojure.org/jira/browse/CLJ-1175

core.memoize probably shouldn't use delays, maybe revert to using atoms like (memoize).

The proposed solution in CLJ-1175 doesn't help in this case since we want to re-call the function causing the exception (again, just like memoize).

Comment by Fogus [ 13/Aug/13 8:22 AM ]

Version 0.5.7-SNAPSHOT has a potential fix in place. If you're so inclined to try it out I would appreciate any feedback that you have.
Thanks.

Comment by Jozef Wagner [ 02/Jan/14 4:46 PM ]

d-lay has an unsynchronized deref, which introduces a race condition between @memory and swap!. Moreover, memory seems to store only one element, so no map is needed there. I suggest something like:

(defn ^:private d-lay [f]
  (let [sentinel (Object.)
        val-ref (atom sentinel)]
    (reify
      clojure.lang.IDeref
      (deref [this]
        (locking sentinel
          (let [val @val-ref]
            (if (identical? sentinel val)
              (let [new-val (f)]
                (reset! val-ref new-val)
                new-val)
              val)))))))




[CMEMOIZE-9] memo-swap! is misnamed Created: 23/Sep/13  Updated: 23/Sep/13

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

Type: Enhancement Priority: Minor
Reporter: Mark Engelberg Assignee: Fogus
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In order to be analogous to atoms, the current behavior of memo-swap! should be called memo-reset! since it overwrites the entire memo map. Similarly, there should be a function called memo-swap! that does an atomic swap operation on the memo cache so, for example, you can add a single value to the cache.






[CMEMOIZE-11] Investigate why build errors occur for Clojure 1.2.0 on IBM JDK 1.6 Created: 29/Nov/13  Updated: 29/Nov/13

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

Type: Defect Priority: Minor
Reporter: Fogus Assignee: Fogus
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The failure report at http://build.clojure.org/job/core.memoize-test-matrix/71/ has more detail. Error messages refer to keyword interning. The dependency has been updated to Clojure 1.2.1 for now.






[CMEMOIZE-10] Odd deprecation warning in face of correct API usage? Created: 29/Nov/13  Updated: 03/Dec/13

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

Type: Defect Priority: Minor
Reporter: Magnar Sveen Assignee: Fogus
Resolution: Unresolved Votes: 0
Labels: documentation, errormsgs
Environment:

[org.clojure/core.memoize "0.5.6"]



 Description   

Calling

(clojure.core.memoize/ttl get-optimized-assets {} :ttl/threshold ms)

Results in this

WARNING - Deprecated construction method for lu cache; prefered way is: (clojure.core.memoize/lu function <base> <:lu/threshold num>)

This breaks my expectation in two ways:

  • If I'm using `ttl` wrong, I would expect a deprecation warning for that. Now I'm a little stuck.
  • If I'm using `ttl` right, I wouldn't expect a deprecation warning.

Now I am just confused. Am I using a deprecated API? In that case, what is the right one to use? Looking at the source code, I see

Please use clojure.core.memoize/ttl instead.

Which is what I am using, as far as I can tell.

Maybe not a very important issue, but it has me confused and unsure.



 Comments   
Comment by Magnar Sveen [ 03/Dec/13 12:12 AM ]

Turns out I got bit by the JVMs global namespace. Once I included 0.5.6, the ring-middleware-format in our stack also started using that updated version - with the wrong API.

Is it only node.js that has this dependency thing figured out properly?

Sorry about the misleading issue. I'd close it, but I don't have the rights to do so.





[CMEMOIZE-12] NPE with memoize/ttl Created: 05/Dec/13  Updated: 19/Feb/14

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

Type: Defect Priority: Minor
Reporter: Scott Morgan Assignee: Fogus
Resolution: Unresolved Votes: 1
Labels: bug
Environment:

org.clojure/core.memoize "0.5.6"



 Description   

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.

java.lang.NullPointerException
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)



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





[CMEMOIZE-13] Reflection warning in clojure.core.memoize/snapshot Created: 14/Jan/14  Updated: 20/Mar/14

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

Type: Defect Priority: Trivial
Reporter: Miikka Koskinen Assignee: Fogus
Resolution: Unresolved Votes: 1
Labels: None
Environment:

core.memoize 0.5.6, Clojure 1.5.1


Attachments: Text File cmemoize-13-v1.patch    
Patch: Code

 Description   

When core.memoize is used with *warn-on-reflection* set to true:

Reflection warning, clojure/core/memoize.clj:72:23 - reference to field cache can't be resolved.


 Comments   
Comment by Andy Fingerhut [ 20/Mar/14 6:49 PM ]

Patch cmemoize-13-v1.patch eliminates the reflection in fn snapshot by type-hinting the value of @cache





Generated at Wed Apr 16 02:50:19 CDT 2014 using JIRA 4.4#649-r158309.