Slowpoke
Rack::Timeout enhancements for Rails
Install / Use
/learn @ankane/SlowpokeREADME
Slowpoke
Rack::Timeout enhancements for Rails
- safer service timeouts
- dynamic timeouts
- custom error pages
Installation
Add this line to your application’s Gemfile:
gem "slowpoke"
And run:
rails generate slowpoke:install
This creates a public/503.html you can customize.
Development
To try out custom error pages in development, temporarily add to config/environments/development.rb:
config.slowpoke.timeout = 1
config.consider_all_requests_local = false
And add a sleep call to one of your actions:
sleep(2)
The custom error page should appear.
Production
The default timeout is 15 seconds. You can change this in config/environments/production.rb with:
config.slowpoke.timeout = 5
For dynamic timeouts, use:
config.slowpoke.timeout = lambda do |env|
request = Rack::Request.new(env)
request.path.start_with?("/admin") ? 15 : 5
end
Subscribe to timeouts with:
ActiveSupport::Notifications.subscribe "timeout.slowpoke" do |name, start, finish, id, payload|
# report timeout
end
To learn more, see the Rack::Timeout documentation.
Safer Service Timeouts
Rack::Timeout can raise an exception at any point in the code, which can leave your app in an unclean state. The safest way to recover from a request timeout is to spawn a new process. This is the default behavior for Slowpoke.
For threaded servers like Puma, this means killing all threads when any one of them times out. This can have a significant impact on performance.
You can customize this behavior with:
Slowpoke.on_timeout do |env|
next if Rails.env.development? || Rails.env.test?
exception = env["action_dispatch.exception"]
if exception && exception.backtrace.first.include?("/active_record/")
Slowpoke.kill
end
end
Note: To access env["action_dispatch.exception"] in development, temporarily add to config/environments/development.rb:
config.consider_all_requests_local = false
Database Timeouts
It’s a good idea to set a statement timeout and a connect timeout. For Postgres, your config/database.yml should include something like:
production:
connect_timeout: 3 # sec
variables:
statement_timeout: 5s
History
View the changelog
Contributing
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features
To get started with development:
git clone https://github.com/ankane/slowpoke.git
cd slowpoke
bundle install
bundle exec rake test
Related Skills
node-connect
349.7kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.7kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.7kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
