Skip to content

Instantly share code, notes, and snippets.

@danownsthisspace
Last active December 4, 2021 13:21
Show Gist options
  • Save danownsthisspace/45402226eca6e5848fce4fc143973d92 to your computer and use it in GitHub Desktop.
Save danownsthisspace/45402226eca6e5848fce4fc143973d92 to your computer and use it in GitHub Desktop.
(ns scratch.core)
;;
;; x "once"
;; debouncer / rate limiter
;; namespaces
;; multiple windows
;; invalidation
;; peek
(defn say-hi [username]
(let [s (str "hello, " username)]
(Thread/sleep (rand 100))
(println s)
s))
(comment (say-hi "Steve"))
(defn wrap-once
"Returns a fn that wraps given function `f` so that:
- First call returns {:okay (apply f args)}.
- Subsequent calls return nil, without executing `f`."
[f]
(let [run?_ (atom false)]
(fn once-fn [& args]
(when (compare-and-set! run?_ false true)
{:okay (apply f args)}))))
(comment
(let [wf (wrap-once say-hi)]
(println "---")
[(future (wf "Steve 1"))
(future (wf "Steve 2"))
(future (wf "Steve 3"))]))
(defn wrap-once-in-a-while
"Returns a fn that wraps given function `f` so that:
- If `f` hasn't been called in >= `msecs-period`:
Call returns {:okay (apply f args)}.
- Otherwise:
Call returns nil, without executing `f`.
`f` will never be called more than once in a given
`msecs-period` even if wrapper is called from multiple
threads."
[msecs-period f]
(let [last-executed_ (atom 0)]
(fn wrapper [args]
(let [now (System/currentTimeMillis)
[old-executed new-executed]
(swap-vals! last-executed_
(fn [last-executed]
(let [elapsed (- now last-executed)]
(if (>= elapsed msecs-period)
now
last-executed))))
changed? (not= old-executed new-executed)]
(when changed?
(try
(do {:okay (apply f args)})
(catch Throwable t {:error t})))))))
(comment
(let [wf (wrap-once-in-a-while 100 say-hi)]
[(wf 1) (wf 2) (wf 3)]))
(comment
((wrap-once-in-a-while say-hi)
"hello"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment