Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Circuit Breakers em Ruby
Search
Lucas Mazza
November 19, 2016
Programming
1
360
Circuit Breakers em Ruby
Lucas Mazza
November 19, 2016
Tweet
Share
More Decks by Lucas Mazza
See All by Lucas Mazza
OpenAPI e Elixir (e qualquer outra linguagem)
lucas
0
47
Ecto sem SQL
lucas
0
350
Feature Toggles! - Elixir
lucas
3
460
Feature Toggles! - Ruby
lucas
2
330
Testes automatizados e a prática antes da teoria
lucas
0
380
The Zen and Art of Refactoring
lucas
4
740
Minitest: voltando ao básico sobre testes
lucas
1
360
10 coisas que eu gostaria de ter aprendido mais cedo
lucas
67
5.3k
gems, executáveis e configurações
lucas
5
360
Other Decks in Programming
See All in Programming
AWSで雰囲気でつくる! VRChatの写真変換ピタゴラスイッチ
anatofuz
0
120
小田原でみんなで一句詠みたいな #phpcon_odawara
stefafafan
0
180
CRE Meetup!ユーザー信頼性を支えるエンジニアリング実践例の発表資料です
tmnb
0
590
エンジニア未経験が最短で戦力になるためのTips
gokana
0
250
Building a macOS screen saver with Kotlin (Android Makers 2025)
zsmb
1
110
SLI/SLOの設定を進めるその前に アラート品質の改善に取り組んだ話
tanden
3
790
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
1.2k
AtCoder Heuristic First-step Vol.1 講義スライド(山登り法・焼きなまし法編)
takumi152
4
1k
Go1.24 go vetとtestsアナライザ
kuro_kurorrr
2
770
Signal-Based Data FetchingWith the New httpResource
manfredsteyer
PRO
0
140
爆速スッキリ! Rspack 移行の成果と道のり - Muddy Web #11
dora1998
1
260
Preact、HooksとSignalsの両立 / Preact: Harmonizing Hooks and Signals
ssssota
1
1.2k
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.2k
Making the Leap to Tech Lead
cromwellryan
133
9.2k
Docker and Python
trallard
44
3.3k
Agile that works and the tools we love
rasmusluckow
328
21k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
30k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
21k
RailsConf 2023
tenderlove
29
1k
For a Future-Friendly Web
brad_frost
176
9.6k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
102
19k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
7
630
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
500
Transcript
Circuit Breakers em Ruby
@lucasmazza http://afterhours.io/
None
None
https://sp.femug.com https://github.com/femug/femug
Circuit Breakers em Ruby
None
None
None
None
❓
None
None
rescue_from StandardError do render text: 'oops' end
rescue_from StandardError do render text: 'oops' end ❓❓❓❓❓❓❓❓❓ ❓❓❓❓❓❓❓❓❓
“You wrap a protected function call in a circuit breaker
object, which monitors for failures.” http://martinfowler.com/bliki/CircuitBreaker.html
https://pragprog.com/book/mnee/release-it
None
None
None
None
None
None
None
None
Estado + transições
✓ Timeouts
✓ Timeouts ✓ Downtimes
✓ Timeouts ✓ Downtimes ✓ Picos de erros
✓ Timeouts ✓ Downtimes ✓ Picos de erros ✓ Má
configuração
★ Limite de falhas
★ Limite de falhas ★ Tempo para reset
★ Limite de falhas ★ Tempo para reset ★ Erros
a ignorar
None
❓API pública ❓Gestão do estado ❓Concorrência
jnunemaker/resilient
require 'resilient/circuit_breaker' circuit_breaker = Resilient::CircuitBreaker.get('acme-co-api') if circuit_breaker.allow_request? begin # API
Call circuit_breaker.success rescue => boom circuit_breaker.failure # do fallback end else # do fallback end
circuit_breaker = Resilient::CircuitBreaker.get('example', { # at what percentage of errors
should we open the circuit error_threshold_percentage: 50, # do not try request again for 5 seconds sleep_window_seconds: 5, # do not open circuit until at least 5 requests have happened request_volume_threshold: 5, }) # etc etc etc
✅ Boa API pública ⚠ Não é distribuído ⚠ Não
é concorrente
✅ Instrumentação & Métricas
shopify/semian
gem 'semian', require: %w(semian semian/redis) def fetch_user User.find(session[:user_id]) rescue Redis::CannotConnectError
nil end
Semian.register(:mysql_shard0, timeout: 0.5, error_threshold: 3, error_timeout: 10) Semian[:mysql_shard0].acquire do #
Perform a MySQL query here end
“Semian is not a trivial library to understand, introduces complexity
and thus should be introduced with care.” https://github.com/shopify/semian#do-i-need-semian
“It is paramount that you understand Semian before including it
in production as you may otherwise be surprised by its behaviour.” https://github.com/shopify/semian#do-i-need-semian
⚠ Monkeypatch ⚠ estado por host ✅ Concorrente
✅ Suporte a instrumentação ✅ Battle tested
orgsync/stoplight
light = Stoplight('acme-co-api') { do_api_call } .with_fallback { do_fallback }
.with_threshold(3) # => Stoplight::Light light.color #=> 'green', 'yellow' ou 'red' light.run
require 'redis' redis = Redis.new data_store = Stoplight::DataStore::Redis.new(redis) Stoplight::Light.default_data_store =
data_store slack = Slack::Notifier.new('http://www.example.com/webhook-url') notifier = Stoplight::Notifier::Slack.new(slack) Stoplight::Light.default_notifiers += [notifier] notifier = Stoplight::Notifier::Logger.new(Rails.logger) Stoplight::Light.default_notifiers += [notifier]
⚠ API não idiomática ✅ Distribuído ✅ Concorrente
✅ Implementação bem legível
netflix/hystrix
None
orgsync/stoplight
class CircuitBreaker def initialize(client, name) @client = client @name =
name end def method_missing(method, *args, &block) Stoplight(@name) { @client.public_send(method, *args, &block) }.run end end
gh_client = GitHub::Client.new('acme-co-oauth2-token') client = CircuitBreaker.new(gh_client, 'client-acme-co') # Requests feito
dentro do Circuit Breaker client.repo('plataformatec/devise') client.repo('plataformatec/simple_form') client.repo('plataformatec/faraday-http-cache')
Pattern + Gem Você!
❓Monitoramento
Métricas
StatsD Librato NewRelic AppSignal …
Notificações
Notificações
Reset manual
❓Fallback vs raise
Escrita vs leitura sync vs async
Executar uma operação em background Retry + backoff
Ler dados de uma API Fallback e/ou cache
None
Obrigado! @lucasmazza