Tickers in Clojure
Our example demonstrates how to use tickers in Clojure. Tickers are used when you want to perform an action repeatedly at regular intervals.
(ns tickers-example
(:require [clojure.core.async :refer [chan go-loop <! >! timeout close!]]))
(defn ticker []
(let [ticker-chan (chan)
done-chan (chan)]
(go-loop []
(let [[val channel] (alts! [(timeout 500) done-chan])]
(if (= channel done-chan)
(println "Ticker stopped")
(do
(>! ticker-chan (java.time.LocalDateTime/now))
(recur)))))
[ticker-chan done-chan]))
(defn main []
(let [[ticker-chan done-chan] (ticker)]
(go-loop []
(when-let [t (<! ticker-chan)]
(println "Tick at" t)
(recur)))
(Thread/sleep 1600)
(>!! done-chan true)
(close! ticker-chan)
(close! done-chan)))
(main)
In this Clojure version, we use core.async
to create channels and manage concurrency, which is similar to Go’s goroutines and channels.
We define a ticker
function that creates two channels: ticker-chan
for sending tick values, and done-chan
for signaling when to stop. The function uses go-loop
to repeatedly send the current time to ticker-chan
every 500 milliseconds, unless a value is received on done-chan
.
In the main
function, we start the ticker and print each tick. After 1600 milliseconds, we signal the ticker to stop by sending a value to done-chan
.
When we run this program, the ticker should tick 3 times before we stop it:
$ lein run
Tick at 2023-06-01T10:30:00.123
Tick at 2023-06-01T10:30:00.623
Tick at 2023-06-01T10:30:01.123
Ticker stopped
This example demonstrates how to implement tickers in Clojure using core.async, providing functionality similar to Go’s tickers.