Hotfix: fn?s were incorrectly reporting true for serializable?
This commit is contained in:
parent
1670535332
commit
537b39aba2
2 changed files with 42 additions and 31 deletions
|
|
@ -659,13 +659,17 @@
|
||||||
|
|
||||||
(defn try-write-serializable [out x]
|
(defn try-write-serializable [out x]
|
||||||
(when (utils/serializable? x)
|
(when (utils/serializable? x)
|
||||||
(try (write-serializable out x) true
|
(try
|
||||||
(catch Throwable _ nil))))
|
(write-serializable out x)
|
||||||
|
true
|
||||||
|
(catch Throwable _ nil))))
|
||||||
|
|
||||||
(defn try-write-readable [out x]
|
(defn try-write-readable [out x]
|
||||||
(when (utils/readable? x)
|
(when (utils/readable? x)
|
||||||
(try (write-readable out x) true
|
(try
|
||||||
(catch Throwable _ nil))))
|
(write-readable out x)
|
||||||
|
true
|
||||||
|
(catch Throwable _ nil))))
|
||||||
|
|
||||||
(defn- try-pr-edn [x]
|
(defn- try-pr-edn [x]
|
||||||
(try
|
(try
|
||||||
|
|
|
||||||
|
|
@ -5,40 +5,50 @@
|
||||||
ObjectOutputStream ObjectInputStream]))
|
ObjectOutputStream ObjectInputStream]))
|
||||||
|
|
||||||
;;;; Fallback type tests
|
;;;; Fallback type tests
|
||||||
;; Unfortunately the only reliable way we can tell if something's
|
;; Unfortunately the only ~reliable way we can tell if something's
|
||||||
;; really serializable/readable is to actually try a full roundtrip.
|
;; really serializable/readable is to actually try a full roundtrip.
|
||||||
|
|
||||||
(defn- memoize-type-test [f-test]
|
(defn- memoize-type-test [test-fn]
|
||||||
(let [cache (atom {})] ; {<type> <type-okay?>}
|
(let [cache (atom {})] ; {<type> <type-okay?>}
|
||||||
(fn [x]
|
(fn [x]
|
||||||
(let [t (type x)
|
(let [t (type x)
|
||||||
;; This is a bit hackish, but no other obvious solutions (?):
|
;; This is a bit hackish, but no other obvious solutions (?):
|
||||||
cacheable? (not (re-find #"__\d+" (str t))) ; gensym form
|
cacheable? (not (re-find #"__\d+" (str t))) ; gensym form
|
||||||
test (fn [] (try (f-test x) (catch Exception _ false)))]
|
test (fn [] (try (test-fn x) (catch Exception _ false)))]
|
||||||
(if-not cacheable? (test)
|
(if cacheable?
|
||||||
@(enc/swap-val! cache t #(if % % (delay (test)))))))))
|
@(enc/swap-val! cache t #(if % % (delay (test))))
|
||||||
|
(test))))))
|
||||||
|
|
||||||
|
(def readable? (memoize-type-test (fn [x] (-> x enc/pr-edn enc/read-edn) true)))
|
||||||
(def serializable?
|
(def serializable?
|
||||||
(memoize-type-test
|
(let [test-fn
|
||||||
(fn [x]
|
(fn [x]
|
||||||
(when (instance? Serializable x)
|
(let [class-name (.getName (class x))
|
||||||
(let [class-name (.getName (class x))
|
class ^Class (Class/forName class-name) ; Try 1st (fail fast)
|
||||||
class ^Class (Class/forName class-name) ; Try 1st (fail fast)
|
bas (ByteArrayOutputStream.)
|
||||||
bas (ByteArrayOutputStream.)
|
_ (.writeObject (ObjectOutputStream. bas) x)
|
||||||
_ (.writeObject (ObjectOutputStream. bas) x)
|
ba (.toByteArray bas)
|
||||||
ba (.toByteArray bas)
|
object (.readObject (ObjectInputStream.
|
||||||
object (.readObject (ObjectInputStream.
|
(ByteArrayInputStream. ba)))]
|
||||||
(ByteArrayInputStream. ba)))]
|
(cast class object)
|
||||||
(cast class object)
|
true))
|
||||||
true)))))
|
|
||||||
|
|
||||||
(def readable? (memoize-type-test (fn [x] (-> x enc/pr-edn enc/read-edn) true)))
|
mtt (memoize-type-test test-fn)]
|
||||||
|
|
||||||
|
(fn [x]
|
||||||
|
(if (instance? Serializable x)
|
||||||
|
(if (fn? x)
|
||||||
|
false ; Reports as true but is unreliable
|
||||||
|
(mtt x))
|
||||||
|
false))))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(enc/qb 1000 (serializable? "Hello world")) ; Cacheable
|
(enc/qb 10000
|
||||||
(enc/qb 1000 (serializable? (fn []))) ; Uncacheable
|
(readable? "Hello world") ; Cacheable
|
||||||
(enc/qb 1000 (readable? "Hello world")) ; Cacheable
|
(serializable? "Hello world") ; Cacheable
|
||||||
(enc/qb 1000 (readable? (fn [])))) ; Uncacheable
|
(readable? (fn [])) ; Uncacheable
|
||||||
|
(serializable? (fn [])) ; Uncacheable
|
||||||
|
))
|
||||||
|
|
||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
|
|
@ -110,11 +120,8 @@
|
||||||
(is? x java.util.UUID)
|
(is? x java.util.UUID)
|
||||||
(is? x java.util.regex.Pattern)
|
(is? x java.util.regex.Pattern)
|
||||||
|
|
||||||
(when (and allow-clojure-reader? (readable? x)) :clojure-reader)
|
(when (and allow-clojure-reader? (readable? x)) :clojure-reader)
|
||||||
(when (and allow-java-serializable?
|
(when (and allow-java-serializable? (serializable? x)) :java-serializable)))))
|
||||||
;; Reports as true but is unreliable:
|
|
||||||
(not (is? x clojure.lang.Fn))
|
|
||||||
(serializable? x)) :java-serializable)))))
|
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(enc/qb 10000 (freezable? "hello")) ; 0.79
|
(enc/qb 10000 (freezable? "hello")) ; 0.79
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue