{"id":30174238,"url":"https://github.com/seuros/breaker_machines","last_synced_at":"2026-04-01T23:24:50.591Z","repository":{"id":303169654,"uuid":"1014431941","full_name":"seuros/breaker_machines","owner":"seuros","description":"Modern circuit breaker for Ruby \u0026 Rails. Thread-safe, fiber-ready async support. Built-in fallbacks, rich introspection, clean DSL. Memory-efficient with jitter \u0026 monitoring.","archived":false,"fork":false,"pushed_at":"2026-03-22T12:17:36.000Z","size":1143,"stargazers_count":108,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-03-23T01:39:32.206Z","etag":null,"topics":["async","circuit-breaker","concurrent-ruby","dsl","error-handling","failover","fallback","fault-tolerance","fiber-safe","high-availability","hystrix","microservices","monitoring","observability","rails","reliability","resilience","ruby","state-machine","thread-safe"],"latest_commit_sha":null,"homepage":null,"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/seuros.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-05T18:00:00.000Z","updated_at":"2026-03-22T12:17:30.000Z","dependencies_parsed_at":"2025-07-06T05:32:55.937Z","dependency_job_id":"cb0e63fc-2757-400c-9c2a-6429896fd702","html_url":"https://github.com/seuros/breaker_machines","commit_stats":null,"previous_names":["seuros/breaker_machines"],"tags_count":45,"template":false,"template_full_name":null,"purl":"pkg:github/seuros/breaker_machines","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Fbreaker_machines","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Fbreaker_machines/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Fbreaker_machines/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Fbreaker_machines/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seuros","download_url":"https://codeload.github.com/seuros/breaker_machines/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Fbreaker_machines/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: 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":["async","circuit-breaker","concurrent-ruby","dsl","error-handling","failover","fallback","fault-tolerance","fiber-safe","high-availability","hystrix","microservices","monitoring","observability","rails","reliability","resilience","ruby","state-machine","thread-safe"],"created_at":"2025-08-12T00:44:43.814Z","updated_at":"2026-04-01T23:24:50.567Z","avatar_url":"https://github.com/seuros.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# BreakerMachines\n\n\u003e The circuit breaker that went where no Ruby has gone before! ⭐\n\nA battle-tested Ruby implementation of the Circuit Breaker pattern, built on `state_machines` for reliable distributed systems protection.\n\n## Quick Start\n\n```bash\ngem 'breaker_machines'\n```\n\n```ruby\nclass PaymentService\n  include BreakerMachines::DSL\n\n  circuit :stripe do\n    threshold failures: 3, within: 1.minute\n    reset_after 30.seconds\n    fallback { { error: \"Payment queued for later\" } }\n  end\n\n  def charge(amount)\n    circuit(:stripe).wrap do\n      Stripe::Charge.create(amount: amount)\n    end\n  end\nend\n```\n\n## A Message to the Resistance\n\nSo AI took your job while you were waiting for Fireship to drop the next JavaScript framework?\n\nWelcome to April 2005—when Git was born, branches were just `master`, and nobody cared about your pronouns. This is the pattern your company's distributed systems desperately need, explained in a way that won't make you fall asleep and impulse-buy developer swag just to feel something.\n\nStill reading? Good. Because in space, nobody can hear you scream about microservices. It's all just patterns and pain.\n\n### The Pattern They Don't Want You to Know\n\nBuilt on the battle-tested `state_machines` gem, because I don't reinvent wheels here—I stop them from catching fire and burning down your entire infrastructure.\n\n## Features\n\n- **Thread-safe** circuit breaker implementation\n- **Fiber-safe mode** for async Ruby (Falcon, async gem)\n- **AsyncCircuit** class with mutex-protected state transitions\n- **Circuit Groups** for managing related circuits with dependencies\n- **Coordinated State Management** for dependency-aware transitions\n- **Cascading Circuit Breakers** for modeling system dependencies\n- **Hedged requests** for latency reduction\n- **Multiple backends** with automatic failover\n- **Bulkheading** to limit concurrent requests\n- **Percentage-based thresholds** with minimum call requirements\n- **Dynamic circuit breakers** with templates for runtime creation\n- **Pluggable storage** (Memory, Redis, Custom)\n- **Rich callbacks** and instrumentation\n- **ActiveSupport::Notifications** integration\n- **Cross-platform support** - Optimized for MRI, JRuby, and TruffleRuby\n\n## Documentation\n\n### Core Features\n- **Getting Started Guide** (docs/GETTING_STARTED.md) - Installation and basic usage\n- **Configuration Reference** (docs/CONFIGURATION.md) - All configuration options\n- **Advanced Patterns** (docs/ADVANCED_PATTERNS.md) - Complex scenarios and patterns\n\n### Advanced Features\n- **Circuit Groups** (docs/CIRCUIT_GROUPS.md) - Managing related circuits with dependencies\n- **Coordinated State Management** (docs/COORDINATED_STATE_MANAGEMENT.md) - Dependency-aware state transitions\n- **Cascading Circuit Breakers** (docs/CASCADING_CIRCUITS.md) - Modeling system dependencies\n\n### Async \u0026 Concurrency\n- **Async Mode** (docs/ASYNC.md) - Fiber-safe operations and AsyncCircuit\n- **Async Storage Examples** (docs/ASYNC_STORAGE_EXAMPLES.md) - Non-blocking storage backends\n\n### Storage \u0026 Persistence\n- **Persistence Options** (docs/PERSISTENCE.md) - Storage backends and distributed state\n\n### Testing\n- **Testing Guide** (docs/TESTING.md) - Testing strategies\n  - [RSpec Testing](docs/TESTING_RSPEC.md)\n  - [ActiveSupport Testing](docs/TESTING_ACTIVESUPPORT.md)\n\n### Integration \u0026 Monitoring\n- **Rails Integration** (docs/RAILS_INTEGRATION.md) - Rails-specific patterns\n- **Observability Guide** (docs/OBSERVABILITY.md) - Monitoring and metrics\n\n### Reference\n- **API Reference** (docs/API_REFERENCE.md) - Complete API documentation\n- **Horror Stories** (docs/HORROR_STORIES.md) - Real production failures and lessons learned\n\n## Why BreakerMachines?\n\nBuilt on the battle-tested `state_machines` gem, BreakerMachines provides production-ready circuit breaker functionality without reinventing the wheel. It's designed for modern Ruby applications with first-class support for fibers, async operations, and distributed systems.\n\nSee [Why I Open Sourced This](docs/WHY_OPEN_SOURCE.md) for the full story.\n\n## Chapter 1: The Year is 2025 (Stardate 2025.186)\n\nThe Resistance huddles in the server rooms, the last bastion against the cascade failures. Outside, the microservices burn. Redis Ship Com is down. PostgreSQL Life Support is flatlining.\n\nAnd somewhere in the darkness, a junior developer is about to write:\n\n```ruby\ndef fetch_user_data\n  retry_count = 0\n  begin\n    @redis.get(user_id)\n  rescue =\u003e e\n    retry_count += 1\n    retry if retry_count \u003c Float::INFINITY  # \"It'll work eventually\"\n  end\nend\n```\n\n\"This,\" whispers the grizzled ops engineer, \"is how civilizations fall.\"\n\n## The Hidden State Machine\n\nThey built this on `state_machines` because sometimes, Resistance, you need a tank, not another JavaScript framework.\n\nSee the [Circuit Breaker State Machine diagram](docs/DIAGRAMS.md#the-circuit-breaker-state-machine) for a visual representation of hope, despair, and the eternal cycle of production failures.\n\n## What You Think You're Doing vs Reality\n\n### You Think: \"I'm implementing retry logic for resilience!\"\n### Reality: You're DDOSing your own infrastructure\n\nSee [The Retry Death Spiral diagram](docs/DIAGRAMS.md#the-retry-death-spiral) to understand how your well-intentioned retries become a self-inflicted distributed denial of service attack.\n\n## Advanced Features\n\n- **Hedged Requests** - Reduce latency with duplicate requests\n- **Multiple Backends** - Automatic failover across endpoints\n- **Percentage-Based Thresholds** - Open on error rates, not just counts\n- **Dynamic Circuit Breakers** - Runtime creation with templates\n- **Apocalypse-Resistant Storage** - Cascading fallbacks when Redis dies\n- **Custom Storage Backends** - SysV semaphores, distributed locks, etc.\n\nSee [Advanced Patterns](docs/ADVANCED_PATTERNS.md) for detailed examples and implementation guides.\n\n## A Word from the RMNS Atlas Monkey\n\n*The Universal Commentary Engine crackles to life:*\n\n\"In space, nobody can hear your pronouns. But they can hear your services failing.\n\nThe universe doesn't care about your bootcamp certificate or your Medium articles about 'Why I Switched to Rust.' It cares about one thing:\n\nDoes your system stay up when Redis has a bad day?\n\nIf not, welcome to the Resistance. We have circuit breakers.\n\nRemember: The pattern isn't about preventing failures—it's about failing fast, failing smart, and living to deploy another day.\n\nAs I always say when contemplating the void: 'It's better to break a circuit than to break production.'\"\n\n*— Universal Commentary Engine, Log Entry 42*\n\n## Contributing to the Resistance\n\n1. Fork it (like it's 2005)\n2. Create your feature branch (`git checkout -b feature/save-the-fleet`)\n3. Commit your changes (`git commit -am 'Add quantum circuit breaker'`)\n4. Push to the branch (`git push origin feature/save-the-fleet`)\n5. Create a new Pull Request (and wait for the Council of Elders to review)\n\n## License\n\nMIT License. See [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n- The `state_machines` gem - The reliable engine under our hood\n- Every service that ever timed out - You taught me well\n- The RMNS Atlas Monkey - For philosophical guidance\n- The Resistance - For never giving up\n\n## Author\n\nBuilt with ❤️ and ☕ by the Resistance against cascading failures.\n\n**Remember: In space, nobody can hear your Redis timeout. But they can feel your circuit breaker failing over to localhost.**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseuros%2Fbreaker_machines","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseuros%2Fbreaker_machines","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseuros%2Fbreaker_machines/lists"}