Created
September 16, 2020 15:05
-
-
Save armed/6376fe49e804e136197ff0a2ce19a942 to your computer and use it in GitHub Desktop.
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
(ns activator.singularizer-cache) | |
(def SINGULARITY (atom {})) | |
(def sing-update-in! | |
(partial swap! SINGULARITY update-in)) | |
(def sing-assoc-in! | |
(partial swap! SINGULARITY assoc-in)) | |
(defn wait-result | |
[func args] | |
(when-let [job (get-in @SINGULARITY [func args :job])] | |
(sing-update-in! [func args :count] inc) | |
(let [result @job] | |
(sing-update-in! [func args :count] dec) | |
(when (= 0 (get-in @SINGULARITY [func args :count])) | |
(sing-assoc-in! [func args :job] nil)) | |
result))) | |
(defn singularize-fn | |
"Takes function and returns new function with | |
singular call restriction. Singular restriction means | |
that function with specific args can be called only once | |
at a time, all other same args parallell calls will be placed | |
in wait queue. Then single result will be pased to all calls." | |
[func] | |
(swap! SINGULARITY assoc func {}) | |
(fn [& args] | |
(if-let [result (wait-result func args)] | |
result | |
(let [job (future (apply func args))] | |
(sing-assoc-in! [func args] {:job job | |
:count 0}) | |
(wait-result func args))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment