{"id":15637660,"url":"https://github.com/jnunemaker/resilient","last_synced_at":"2025-04-06T14:12:29.590Z","repository":{"id":52346396,"uuid":"47457997","full_name":"jnunemaker/resilient","owner":"jnunemaker","description":":electric_plug: circuit breaker based on netflix/hystrix but in ruby, hopefully commands/semaphores eventually too","archived":false,"fork":false,"pushed_at":"2023-11-29T17:17:53.000Z","size":184,"stargazers_count":105,"open_issues_count":3,"forks_count":6,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-30T12:09:20.648Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jnunemaker.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-05T14:05:09.000Z","updated_at":"2025-01-15T23:33:31.000Z","dependencies_parsed_at":"2024-10-22T19:11:27.779Z","dependency_job_id":null,"html_url":"https://github.com/jnunemaker/resilient","commit_stats":{"total_commits":199,"total_committers":4,"mean_commits":49.75,"dds":0.02010050251256279,"last_synced_commit":"5ee80669f37e3e244eea4ade3d72c7b1ab01868a"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jnunemaker%2Fresilient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jnunemaker%2Fresilient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jnunemaker%2Fresilient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jnunemaker%2Fresilient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jnunemaker","download_url":"https://codeload.github.com/jnunemaker/resilient/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247492557,"owners_count":20947545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-03T11:12:26.202Z","updated_at":"2025-04-06T14:12:29.559Z","avatar_url":"https://github.com/jnunemaker.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Resilient\n\nSome tools to aid in resiliency in Ruby. For now, just a circuit breaker (~~stolen from~~ based on [hystrix](https://github.com/netflix/hystrix)). Soon much more...\n\nNothing asynchronous or thread safe yet either, but open to it and would like to see more around it in the future. See more here: [jnunemaker/resilient#18](https://github.com/jnunemaker/resilient/issues/18).\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem \"resilient\"\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install resilient\n\n## Usage\n\n```ruby\nrequire \"resilient/circuit_breaker\"\n\n# default properties for circuit, CircuitBreaker.get is used instead of\n# CircuitBreaker.new as `get` keeps a registry of circuits by key to prevent\n# creating multiple instances of the same circuit breaker for a key; not using\n# `get` means you would have multiple instances of the circuit breaker and thus\n# separate state and metrics; you can read more in examples/get_vs_new.rb\ncircuit_breaker = Resilient::CircuitBreaker.get(\"example\")\nif circuit_breaker.allow_request?\n  begin\n    # do something expensive\n    circuit_breaker.success\n  rescue =\u003e boom\n    circuit_breaker.failure\n    # do fallback\n  end\nelse\n  # do fallback\nend\n```\n\ncustomize properties of circuit:\n\n```ruby\ncircuit_breaker = Resilient::CircuitBreaker.get(\"example\", {\n  # at what percentage of errors should we open the circuit\n  error_threshold_percentage: 50,\n  # do not try request again for 5 seconds\n  sleep_window_seconds: 5,\n  # do not open circuit until at least 5 requests have happened\n  request_volume_threshold: 5,\n})\n# etc etc etc\n```\n\nforce the circuit to be always open:\n\n```ruby\ncircuit_breaker = Resilient::CircuitBreaker.get(\"example\", force_open: true)\n# etc etc etc\n```\n\nforce the circuit to be always closed (great way to test in production with no impact, all instrumentation still runs which means you can measure in production with config and gain confidence while never actually opening a circuit incorrectly):\n\n```ruby\ncircuit_breaker = Resilient::CircuitBreaker.get(\"example\", force_closed: true)\n# etc etc etc\n```\n\ncustomize rolling window to be 10 buckets of 1 second each (10 seconds in all):\n\n```ruby\ncircuit_breaker = Resilient::CircuitBreaker.get(\"example\", {\n  window_size_in_seconds: 10,\n  bucket_size_in_seconds: 1,\n})\n# etc etc etc\n```\n\n## Default Properties\n\nProperty                        | Default                | Notes\n--------------------------------|------------------------|--------\n**:force_open**                 | `false`                  | allows forcing the circuit open (stopping all requests)\n**:force_closed**               | `false`                  | allows ignoring errors and therefore never trip \"open\" (e.g. allow all traffic through); normal instrumentation will still happen, thus allowing you to \"test\" configuration live without impact\n**:instrumenter**               | `Instrumenters::Noop`    | what to use to instrument all events that happen (e.g.  `ActiveSupport::Notifications`)\n**:sleep_window_seconds**       | `5`                      | seconds after tripping circuit before allowing retry\n**:request_volume_threshold**   | `20`                     | number of requests that must be made within a statistical window before open/close decisions are made using stats\n**:error_threshold_percentage** | `50`                     |  % of \"marks\" that must be failed to trip the circuit\n**:window_size_in_seconds**     | `60`                     | number of seconds in the statistical window\n**:bucket_size_in_seconds**     | `10`                     | size of buckets in statistical window\n**:metrics**                    | `Resilient::Metrics.new` | metrics instance used to keep track of success and failure\n\n## Tests\n\nTo ensure that you have clean circuit breakers for each test case, be sure to run the following in the setup for your tests (which resets the default registry and thus clears all the registered circuits) either before every test case or at a minimum each test case that uses circuit breakers.\n\n```ruby\nResilient::CircuitBreaker::Registry.reset\n```\n\n**Note**: If you use a non-default registry, you'll need to reset that on your own. If you don't know what I'm talking about, you are fine.\n\n## Development\n\n```bash\n# install dependencies\nscript/bootstrap\n\n# run tests\nscript/test\n\n# ...or to auto run tests with guard\nscript/watch\n\n# to get a shell to play in\nscript/console\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/jnunemaker/resilient.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n\n## Release (for maintainers)\n\n* increment version based on semver\n* git commit version change\n* script/release (releases to rubygems and git tags)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjnunemaker%2Fresilient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjnunemaker%2Fresilient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjnunemaker%2Fresilient/lists"}