token-bucket-rate-limiter-clj

Clojure
(defn token-bucket
  "Returns a stateful fn that takes one token per call, or false when empty."
  [capacity refill-per-sec]
  (let [state (atom {:tokens (double capacity) :last (System/nanoTime)})]
    (fn []
      (let [now (System/nanoTime)]
        (-> (swap! state
                   (fn [{:keys [tokens last]}]
                     (let [elapsed (/ (- now last) 1e9)
                           tokens  (min (double capacity)
                                        (+ tokens (* elapsed refill-per-sec)))]
                       (if (>= tokens 1.0)
                         {:tokens (- tokens 1.0) :last now :ok true}
                         {:tokens tokens :last now :ok false}))))
            :ok)))))