File: README.md

package info (click to toggle)
ruby-slowpoke 0.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 96 kB
  • sloc: ruby: 99; makefile: 7
file content (152 lines) | stat: -rw-r--r-- 3,772 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# Slowpoke

[Rack::Timeout](https://github.com/heroku/rack-timeout) enhancements for Rails

- safer service timeouts
- dynamic timeouts
- custom error pages

## Installation

Add this line to your application’s Gemfile:

```ruby
gem 'slowpoke'
```

And run:

```sh
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`:

```ruby
config.slowpoke.timeout = 1
config.consider_all_requests_local = false
```

And add a `sleep` call to one of your actions:

```ruby
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:

```ruby
config.slowpoke.timeout = 5
```

For dynamic timeouts, use:

```ruby
config.slowpoke.timeout = lambda do |env|
  request = Rack::Request.new(env)
  request.path.start_with?("/admin") ? 15 : 5
end
```

Subscribe to timeouts with:

```ruby
ActiveSupport::Notifications.subscribe "timeout.slowpoke" do |name, start, finish, id, payload|
  # report timeout
end
```

To learn more, see the [Rack::Timeout documentation](https://github.com/heroku/rack-timeout).

## Safer Service Timeouts

Rack::Timeout can raise an exception at any point in the code, which can leave your app in an [unclean state](https://www.schneems.com/2017/02/21/the-oldest-bug-in-ruby-why-racktimeout-might-hose-your-server/). 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:

```ruby
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`:

```ruby
config.consider_all_requests_local = false
```

## Database Timeouts

It’s a good idea to set a [statement timeout](https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts/#statement-timeouts-1) and a [connect timeout](https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts/#activerecord). For Postgres, your `config/database.yml` should include something like:

```yml
production:
  connect_timeout: 3 # sec
  variables:
    statement_timeout: 5s
```

## Upgrading

### 0.3.0

If you set the timeout with:

```ruby
Slowpoke.timeout = 5
```

Remove it and add to `config/environments/production.rb`:

```ruby
config.slowpoke.timeout = 5
```

If you use migration timeouts, check out [this guide](https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts/#statement-timeouts-1) for how to configure them directly in `config/database.yml`.

### 0.1.0

`0.1.0` removes database timeouts, since Rails supports them by default. To restore the previous behavior, use:

```yaml
production:
  variables:
    statement_timeout: <%= Slowpoke.timeout * 1000 %>
```

## History

View the [changelog](https://github.com/ankane/slowpoke/blob/master/CHANGELOG.md)

## Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

- [Report bugs](https://github.com/ankane/slowpoke/issues)
- Fix bugs and [submit pull requests](https://github.com/ankane/slowpoke/pulls)
- Write, clarify, or fix documentation
- Suggest or add new features

To get started with development:

```sh
git clone https://github.com/ankane/slowpoke.git
cd slowpoke
bundle install
```