Last active
August 14, 2025 03:07
-
-
Save pmonks/d3bbf08ccc722f2dcf9b8c81ff9db7b8 to your computer and use it in GitHub Desktop.
A configurable polling alternative to clojure.core/add-watch
This file contains hidden or 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
; | |
; 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