Last active
July 7, 2022 19:57
-
-
Save RutledgePaulV/593a47e18160be2427ebdc8ef25d035a to your computer and use it in GitHub Desktop.
self-cleaning-pool.clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn gc-managed-pool | |
"Wraps a manually managed pool to create an automatically managed pool | |
that returns resources to the pool as the doled out references are | |
garbage collected by the jvm." | |
[pool borrow return] | |
(letfn [(interfaces [x] | |
(->> (ancestors (class x)) | |
(filter class?) | |
(filter #(.isInterface %)))) | |
(create-facade [x] | |
(Proxy/newProxyInstance | |
(.getClassLoader (class x)) | |
(into-array Class (interfaces x)) | |
(reify InvocationHandler | |
(invoke [this proxy method args] | |
(.invoke method x args)))))] | |
(let [queue (ReferenceQueue.) | |
references (atom #{})] | |
(future | |
(loop [] | |
(when-some [ref (.remove queue)] | |
(let [{:keys [resource]} (meta ref)] | |
(try | |
(swap! references disj resource) | |
(return pool resource) | |
(finally (.clear ref))) | |
(recur))))) | |
(fn [& args] | |
(let [created (apply borrow pool args) | |
view (create-facade created) | |
state {:resource created} | |
reference (proxy [WeakReference IMeta] [view queue] | |
(meta [] state))] | |
(swap! references conj created) | |
view))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wraps a manually managed resource pool with logic that returns resources to the pool as the doled out references are garbage collected by the JVM.