Skip to content

Instantly share code, notes, and snippets.

@pmonks
Last active August 14, 2025 03:07
Show Gist options
  • Save pmonks/d3bbf08ccc722f2dcf9b8c81ff9db7b8 to your computer and use it in GitHub Desktop.
Save pmonks/d3bbf08ccc722f2dcf9b8c81ff9db7b8 to your computer and use it in GitHub Desktop.
A configurable polling alternative to clojure.core/add-watch
;
; Copyright © 2022 Peter Monks
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at https://mozilla.org/MPL/2.0/.
;
; SPDX-License-Identifier: MPL-2.0
;
(defn poll-atom
"Polls atom `a` every `poll-interval-ms` and calls `f` (a function of one
argument - the current value of the atom), if it has changed. Will return
`nil` when promise `p` is delivered a logically `false` value"
[a p ^long poll-interval-ms f]
(loop [previous-value ::undefined]
(let [current-value @a]
(when (not= current-value previous-value)
(f current-value))
(when (deref p poll-interval-ms true)
(recur current-value))))
nil)
; Example usage
(let [a (atom 0)
running? (promise)
f (future (poll-atom a running? 1000 println))] ; Poll a every second and print it
(run! (fn [_] (do (swap! a inc) (Thread/sleep 10))) (range 1000)) ; Increment a to 1000, slowly
(deliver running? false)
@f) ; Ensures that any exceptions thrown inside the future are rethrown
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment