{"id":32187379,"url":"https://github.com/nabato/diehard-async","last_synced_at":"2026-02-23T14:01:03.384Z","repository":{"id":153778694,"uuid":"629095045","full_name":"nabato/diehard-async","owner":"nabato","description":"Clojure resilience library including retry, circuit breaker, rate limiter, bulkhead, timeout and fallback","archived":false,"fork":false,"pushed_at":"2023-04-22T19:45:53.000Z","size":43,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-14T07:41:59.975Z","etag":null,"topics":["bulkhead","circuit-breaker","clojure","fallback","rate-limiter","rate-limiting","resilience","retry-library","timeout","timeout-library"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nabato.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-04-17T15:54:01.000Z","updated_at":"2023-04-22T06:52:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"c40c7b23-5bb2-4498-a72f-6daa17231abb","html_url":"https://github.com/nabato/diehard-async","commit_stats":null,"previous_names":["nabato/diehard-async","vlnabatov/diehard-async"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nabato/diehard-async","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabato%2Fdiehard-async","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabato%2Fdiehard-async/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabato%2Fdiehard-async/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabato%2Fdiehard-async/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nabato","download_url":"https://codeload.github.com/nabato/diehard-async/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabato%2Fdiehard-async/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29596186,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T20:59:56.587Z","status":"ssl_error","status_checked_at":"2026-02-18T20:58:41.434Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bulkhead","circuit-breaker","clojure","fallback","rate-limiter","rate-limiting","resilience","retry-library","timeout","timeout-library"],"created_at":"2025-10-22T00:02:58.279Z","updated_at":"2026-02-22T06:31:09.953Z","avatar_url":"https://github.com/nabato.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# diehard-async\n\nClojure library to provide safety guard to your application.\nSome of the functionality is wrapper over\n[Failsafe](https://github.com/jhalterman/failsafe)., is itself a fork of [diehard](https://github.com/sunng87/diehard)\n\nNote that from 0.7 diehard-async uses Clojure 1.9 and spec.alpha for\nconfiguration validation. Clojure 1.8 users could stick with diehard-async\n`0.6.0`.\n\n## Usage\n\nA quick example for diehard-async usage.\n\n### Retry block\n\nA retry block will re-execute inner forms when retry criteria matches.\n\n```clojure\n(require '[diehard-async.core :as dh])\n(dh/with-retry {:retry-on    TimeoutException\n                :max-retries 3}\n  (fetch-data-from-the-moon))\n```\n\n### Circuit breaker\n\nA circuit breaker will track the execution of inner block and skip\nexecution if the open condition triggered.\n\n```clojure\n(require '[diehard-async.core :as dh])\n\n(defcircuitbreaker my-cb {:failure-threshold-ratio [8 10]\n                          :delay-ms                1000})\n\n(dh/with-circuit-breaker my-cb\n  (fetch-data-from-the-moon))\n\n(dh/with-circuit-breaker {:circuit-breaker my-cb :async :default}\n  (fetch-data-from-the-moon-asynchronously))\n\n(dh/with-circuit-breaker\n                {:circuit-breaker my-cb :async :execution}\n                (fn [^AsyncExecution execution]\n                  (fetch-data-from-the-moon-asynchronously\n                           {:on-result         #(.recordResult execution %)\n                            :on-exception      #(.recordException execution %)})))\n```\n\n### Rate limiter\n\nA rate limiter protects your code block to run limited times per\nsecond. It will block or throw exception depends on your\nconfiguration.\n\n```clojure\n(require '[diehard-async.core :as dh])\n\n(defratelimiter my-rl {:rate 100})\n\n(dh/with-rate-limiter my-rl\n  (send-people-to-the-moon))\n```\n\n### Bulkhead\n\nBulkhead allows you to limit concurrent execution on a code block.\n\n```clojure\n(require '[diehard-async.core :as dh])\n\n;; at most 10 threads can run the code block concurrently\n(defbulkhead my-bh {:concurrency 10})\n\n(dh/with-bulkhead my-bh\n  (send-people-to-the-moon))\n```\n\n### Timeout\n\nTimeouts allow you to fail an execution with `TimeoutExceededException` if it takes too long to complete\n\n```clojure\n(require '[diehard-async.core :as dh])\n\n(with-timeout {:timeout-ms 5000}\n  (fly-me-to-the-moon))\n```\n\n## Examples\n\n### Retry block\n\n```clojure\n(dh/with-retry {:retry-on          Exception\n                :max-retries       3\n                :on-retry          (fn [val ex] (prn \"retrying...\"))\n                :on-failure        (fn [_ _] (prn \"failed...\"))\n                :on-failed-attempt (fn [_ _] (prn \"failed attempt\"))\n                :on-success        (fn [_] (prn \"did it! success!\"))}\n               (throw (ex-info \"not good\" {:not \"good\"})))\n```\n\noutput:\n\n```\n\"failed attempt\"\n\"retrying...\"\n\"failed attempt\"\n\"retrying...\"\n\"failed attempt\"\n\"retrying...\"\n\"failed attempt\"\n\"failed...\"\nExecution error (ExceptionInfo) at main.user$eval27430$reify__27441/get (form-init6791465293873302710.clj:7).\nnot good\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnabato%2Fdiehard-async","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnabato%2Fdiehard-async","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnabato%2Fdiehard-async/lists"}