Skip to content

Instantly share code, notes, and snippets.

@jcf
Created May 27, 2015 13:13
Show Gist options
  • Save jcf/18b9d64b7ae7b4f45ba7 to your computer and use it in GitHub Desktop.
Save jcf/18b9d64b7ae7b4f45ba7 to your computer and use it in GitHub Desktop.
core.async retry
(ns com.example.util
(:import [clojure.core.async.impl.channels ManyToManyChannel])
(:require [clojure.core.async :as async]))
(defn retry
[f & {:keys [out-ch retries delay]}]
{:pre [(and (integer? retries) (pos? retries))
(integer? delay)
(instance? ManyToManyChannel out-ch)]}
(let [stop-ch (async/chan 1)]
(async/go-loop [n 0]
(when (< n retries)
(let [result (async/<! (async/thread
(try
(f)
(catch Exception ex
{::fail ex}))))]
(if (::fail result)
(async/alt!
(async/timeout delay) (recur (inc n))
stop-ch :stopped)
(do
(if (some? result) (async/>! out-ch result))
(async/close! stop-ch)
(async/close! out-ch))))))
stop-ch))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment