solid_queue_guard 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +12 -0
  3. data/.rubocop.yml +44 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +81 -0
  6. data/Gemfile +8 -0
  7. data/Gemfile.lock +308 -0
  8. data/README.md +79 -14
  9. data/app/controllers/solid_queue_guard/application_controller.rb +1 -0
  10. data/app/controllers/solid_queue_guard/health_controller.rb +22 -1
  11. data/lib/generators/solid_queue_guard/install/USAGE.ci +9 -0
  12. data/lib/generators/solid_queue_guard/install/ci_generator.rb +19 -0
  13. data/lib/generators/solid_queue_guard/install/templates/solid_queue_guard.rb +11 -1
  14. data/lib/generators/solid_queue_guard/install/templates/solid_queue_guard.yml +25 -0
  15. data/lib/solid_queue_guard/checks/base.rb +16 -0
  16. data/lib/solid_queue_guard/checks/config/async_supervisor_config_check.rb +25 -0
  17. data/lib/solid_queue_guard/checks/config/puma_colocated_check.rb +5 -11
  18. data/lib/solid_queue_guard/checks/config/topology_recommendation_check.rb +24 -0
  19. data/lib/solid_queue_guard/checks/registry.rb +9 -2
  20. data/lib/solid_queue_guard/checks/runtime/base.rb +1 -5
  21. data/lib/solid_queue_guard/checks/runtime/blocked_jobs_check.rb +20 -1
  22. data/lib/solid_queue_guard/checks/runtime/database_support.rb +40 -0
  23. data/lib/solid_queue_guard/checks/runtime/dispatcher_check.rb +26 -1
  24. data/lib/solid_queue_guard/checks/runtime/failed_jobs_check.rb +21 -1
  25. data/lib/solid_queue_guard/checks/runtime/finished_jobs_growth_check.rb +20 -1
  26. data/lib/solid_queue_guard/checks/runtime/orphaned_claims_check.rb +18 -1
  27. data/lib/solid_queue_guard/checks/runtime/paused_queue_lag_check.rb +22 -1
  28. data/lib/solid_queue_guard/checks/runtime/pidfile_check.rb +33 -1
  29. data/lib/solid_queue_guard/checks/runtime/process_topology_check.rb +31 -1
  30. data/lib/solid_queue_guard/checks/runtime/puma_plugin_runtime_check.rb +39 -0
  31. data/lib/solid_queue_guard/checks/runtime/queue_lag_check.rb +30 -1
  32. data/lib/solid_queue_guard/checks/runtime/recurring_stale_check.rb +29 -1
  33. data/lib/solid_queue_guard/checks/runtime/scheduled_backlog_check.rb +18 -1
  34. data/lib/solid_queue_guard/checks/runtime/stale_process_check.rb +19 -1
  35. data/lib/solid_queue_guard/cli.rb +10 -1
  36. data/lib/solid_queue_guard/configuration.rb +36 -1
  37. data/lib/solid_queue_guard/engine.rb +12 -0
  38. data/lib/solid_queue_guard/formatters/terminal.rb +1 -1
  39. data/lib/solid_queue_guard/health/cache.rb +28 -0
  40. data/lib/solid_queue_guard/health/payload.rb +50 -0
  41. data/lib/solid_queue_guard/http_status_policy.rb +35 -0
  42. data/lib/solid_queue_guard/metrics/exporter.rb +34 -0
  43. data/lib/solid_queue_guard/metrics/open_telemetry.rb +19 -0
  44. data/lib/solid_queue_guard/metrics/prometheus.rb +21 -0
  45. data/lib/solid_queue_guard/metrics/statsd.rb +25 -0
  46. data/lib/solid_queue_guard/notifier.rb +76 -0
  47. data/lib/solid_queue_guard/notifiers/base.rb +2 -7
  48. data/lib/solid_queue_guard/puma_plugin_support.rb +35 -0
  49. data/lib/solid_queue_guard/recommendations/topology.rb +76 -0
  50. data/lib/solid_queue_guard/runner.rb +10 -1
  51. data/lib/solid_queue_guard/tasks.rb +1 -1
  52. data/lib/solid_queue_guard/version.rb +1 -1
  53. data/lib/solid_queue_guard.rb +1 -1
  54. data/solid_queue_guard.gemspec +54 -0
  55. metadata +25 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd60b98c25c507b3069f98b6b69282f627a398e96bd43d7a5d0713f0499c8610
4
- data.tar.gz: c60a8995c311f4935456f58ca950e1d4cdb4b7e601dc1e6290f62f9d06931cb0
3
+ metadata.gz: 690433fe81ac90880ec7fdaa046b7638330eb879776e19343066732fd1f0f3e7
4
+ data.tar.gz: 6028bf63b80b0919158a10fb5771b8cdec74518be47b0882cfd39f893bbf10f7
5
5
  SHA512:
6
- metadata.gz: ac5fbbb57df0cb133466076f0c4c1b698a13004b3f44e22bc64139e04e8c4bb51973a22e534ff0617329709a154a92a7a93ac9e083ea0087d86dadc73c6e89cf
7
- data.tar.gz: b16bc3883213b26928b0cfa2c4d0b355ce43bd956a4c3df27e4cad4f8f71534748a15e5f9c892190a018741df8c9f1fbe4aaaa577e960f4e39a2a28c00a823ed
6
+ metadata.gz: 2d9bf3c79fbe0871ed9456eec1cefb22baf52f4949b128cc2a1f8d30dde4bb468bbece87752a33ea06a0e53d12ec25db65e1c1295205ac140643d9cf5dbfc769
7
+ data.tar.gz: 0d40a0805708376a56e243977772274a61f6e4a799ca3dfc64dfb362a46217e30258ba1758e1dda7bc3956f63e13895cde6814f446551b4bf271a07b24477e57
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /Gemfile.lock.bak
3
+ /pkg/
4
+ /tmp/
5
+ /*.gem
6
+ /solid_queue_guard-*/
7
+
8
+ /test/dummy/db/*.sqlite3
9
+ /test/dummy/log/*
10
+ !/test/dummy/log/.keep
11
+ /test/dummy/tmp/*
12
+ !/test/dummy/tmp/.keep
data/.rubocop.yml ADDED
@@ -0,0 +1,44 @@
1
+ plugins:
2
+ - rubocop-rails
3
+
4
+ AllCops:
5
+ NewCops: enable
6
+ TargetRubyVersion: 3.1
7
+ SuggestExtensions: false
8
+ Exclude:
9
+ - "gemfiles/**/*"
10
+ - "test/dummy/**/*"
11
+ - "vendor/**/*"
12
+ - "tmp/**/*"
13
+
14
+ Style/Documentation:
15
+ Enabled: false
16
+
17
+ Metrics/BlockLength:
18
+ Exclude:
19
+ - "Rakefile"
20
+ - "*.gemspec"
21
+ - "lib/solid_queue_guard/tasks.rb"
22
+
23
+ Metrics/MethodLength:
24
+ Max: 25
25
+
26
+ Metrics/AbcSize:
27
+ Max: 25
28
+ Exclude:
29
+ - lib/solid_queue_guard/checks/runtime/**/*
30
+
31
+ Gemspec/DevelopmentDependencies:
32
+ Enabled: false
33
+
34
+ Rails/Exit:
35
+ Exclude:
36
+ - "lib/solid_queue_guard/cli.rb"
37
+
38
+ Naming/PredicateMethod:
39
+ Exclude:
40
+ - "lib/solid_queue_guard/tasks.rb"
41
+
42
+ Style/MultilineBlockChain:
43
+ Exclude:
44
+ - "lib/solid_queue_guard/checks/runtime/**/*"
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.4.9
data/CHANGELOG.md ADDED
@@ -0,0 +1,81 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2026-07-09
9
+
10
+ ### Added
11
+
12
+ - Stable public API guarantee documented in README
13
+ - Gemspec packaging via `git ls-files` for reproducible releases
14
+
15
+ ### Changed
16
+
17
+ - Deprecations now target removal in `2.0` per semver policy
18
+
19
+ ## [0.8.0] - 2026-07-09
20
+
21
+ ### Added
22
+
23
+ - Configurable HTTP status policy via `degraded_http_status` and `unhealthy_http_status`
24
+ - `solid_queue_guard:install:ci` generator for GitHub Actions doctor workflow
25
+
26
+ ## [0.7.0] - 2026-07-09
27
+
28
+ ### Added
29
+
30
+ - `AsyncSupervisorConfigCheck` for async supervisor mode
31
+ - `PumaPluginRuntimeCheck` for co-located Puma plugin health
32
+ - Async-aware topology pool recommendations
33
+
34
+ ## [0.6.0] - 2026-07-09
35
+
36
+ ### Added
37
+
38
+ - Per-check configuration via `disabled_checks` and `config.checks`
39
+ - Per-check threshold overrides for queue lag, failed jobs, stale processes, and scheduled backlog
40
+
41
+ ## [0.5.0] - 2026-07-09
42
+
43
+ ### Added
44
+
45
+ - `TopologyRecommendationCheck` for automatic `queue.yml` and pool recommendations
46
+ - `SolidQueueGuard::Recommendations::Topology` analyzer
47
+
48
+ ## [0.4.0] - 2026-07-09
49
+
50
+ ### Added
51
+
52
+ - Metrics export via `config.metrics_backends` (`:statsd`, `:prometheus`, `:opentelemetry`)
53
+ - `SolidQueueGuard::Metrics::Exporter` and per-backend exporters
54
+
55
+ ## [0.3.0] - 2026-07-09
56
+
57
+ ### Added
58
+
59
+ - Notification adapters: `:rails_logger`, `:slack`, `:datadog`, `:webhook`
60
+ - Automatic notification delivery on degraded/unhealthy CLI reports via `config.notify_with`
61
+
62
+ ## [0.2.0] - 2026-07-09
63
+
64
+ ### Added
65
+
66
+ - Runtime checks: queue lag, stale processes, dispatcher health, scheduled backlog, blocked jobs, orphaned claims, failed jobs, recurring staleness, paused queue lag, pidfile, finished jobs growth
67
+ - HTTP `/solid_queue_guard/health` endpoint with optional token auth and response caching
68
+ - `health` rake task now runs full runtime scope
69
+ - Terminal report hides skipped runtime checks
70
+ - Optional Rails `/up` integration via `integrate_rails_health`
71
+
72
+ ## [0.1.0] - 2026-07-09
73
+
74
+ ### Added
75
+
76
+ - `solid_queue_guard:doctor` rake task for configuration readiness checks
77
+ - `solid_queue_guard:report` rake task for full diagnostic output
78
+ - `solid_queue_guard:install` generator for the initializer
79
+ - JSON output via `SOLID_QUEUE_GUARD_FORMAT=json` or `doctor[json]`
80
+ - Strict CI mode via `SOLID_QUEUE_GUARD_STRICT=1` or `--strict`
81
+ - Configuration checks: adapter, queue database, `connects_to`, queue schema, thread pool, worker coverage, scheduler, environment flags, process heartbeat thresholds, and Puma co-location
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ # RuboCop 1.75+ can pull parallel 2.x, which requires Ruby >= 3.3.
8
+ gem 'parallel', '~> 1.26'
data/Gemfile.lock ADDED
@@ -0,0 +1,308 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ solid_queue_guard (1.0.0)
5
+ actionpack (>= 7.1, < 9.0)
6
+ activejob (>= 7.1, < 9.0)
7
+ activerecord (>= 7.1, < 9.0)
8
+ activesupport (>= 7.1, < 9.0)
9
+ railties (>= 7.1, < 9.0)
10
+ solid_queue (>= 1.0, < 2.0)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ action_text-trix (2.1.19)
16
+ railties
17
+ actioncable (8.1.3)
18
+ actionpack (= 8.1.3)
19
+ activesupport (= 8.1.3)
20
+ nio4r (~> 2.0)
21
+ websocket-driver (>= 0.6.1)
22
+ zeitwerk (~> 2.6)
23
+ actionmailbox (8.1.3)
24
+ actionpack (= 8.1.3)
25
+ activejob (= 8.1.3)
26
+ activerecord (= 8.1.3)
27
+ activestorage (= 8.1.3)
28
+ activesupport (= 8.1.3)
29
+ mail (>= 2.8.0)
30
+ actionmailer (8.1.3)
31
+ actionpack (= 8.1.3)
32
+ actionview (= 8.1.3)
33
+ activejob (= 8.1.3)
34
+ activesupport (= 8.1.3)
35
+ mail (>= 2.8.0)
36
+ rails-dom-testing (~> 2.2)
37
+ actionpack (8.1.3)
38
+ actionview (= 8.1.3)
39
+ activesupport (= 8.1.3)
40
+ nokogiri (>= 1.8.5)
41
+ rack (>= 2.2.4)
42
+ rack-session (>= 1.0.1)
43
+ rack-test (>= 0.6.3)
44
+ rails-dom-testing (~> 2.2)
45
+ rails-html-sanitizer (~> 1.6)
46
+ useragent (~> 0.16)
47
+ actiontext (8.1.3)
48
+ action_text-trix (~> 2.1.15)
49
+ actionpack (= 8.1.3)
50
+ activerecord (= 8.1.3)
51
+ activestorage (= 8.1.3)
52
+ activesupport (= 8.1.3)
53
+ globalid (>= 0.6.0)
54
+ nokogiri (>= 1.8.5)
55
+ actionview (8.1.3)
56
+ activesupport (= 8.1.3)
57
+ builder (~> 3.1)
58
+ erubi (~> 1.11)
59
+ rails-dom-testing (~> 2.2)
60
+ rails-html-sanitizer (~> 1.6)
61
+ activejob (8.1.3)
62
+ activesupport (= 8.1.3)
63
+ globalid (>= 0.3.6)
64
+ activemodel (8.1.3)
65
+ activesupport (= 8.1.3)
66
+ activerecord (8.1.3)
67
+ activemodel (= 8.1.3)
68
+ activesupport (= 8.1.3)
69
+ timeout (>= 0.4.0)
70
+ activestorage (8.1.3)
71
+ actionpack (= 8.1.3)
72
+ activejob (= 8.1.3)
73
+ activerecord (= 8.1.3)
74
+ activesupport (= 8.1.3)
75
+ marcel (~> 1.0)
76
+ activesupport (8.1.3)
77
+ base64
78
+ bigdecimal
79
+ concurrent-ruby (~> 1.0, >= 1.3.1)
80
+ connection_pool (>= 2.2.5)
81
+ drb
82
+ i18n (>= 1.6, < 2)
83
+ json
84
+ logger (>= 1.4.2)
85
+ minitest (>= 5.1)
86
+ securerandom (>= 0.3)
87
+ tzinfo (~> 2.0, >= 2.0.5)
88
+ uri (>= 0.13.1)
89
+ appraisal (2.5.0)
90
+ bundler
91
+ rake
92
+ thor (>= 0.14.0)
93
+ ast (2.4.3)
94
+ base64 (0.3.0)
95
+ bigdecimal (4.1.2)
96
+ builder (3.3.0)
97
+ concurrent-ruby (1.3.7)
98
+ connection_pool (3.0.2)
99
+ crass (1.0.7)
100
+ date (3.5.1)
101
+ debug (1.11.1)
102
+ irb (~> 1.10)
103
+ reline (>= 0.3.8)
104
+ drb (2.2.3)
105
+ erb (6.0.4)
106
+ erubi (1.13.1)
107
+ et-orbi (1.4.0)
108
+ tzinfo
109
+ fugit (1.12.3)
110
+ et-orbi (~> 1.4)
111
+ raabro (~> 1.4)
112
+ globalid (1.4.0)
113
+ activesupport (>= 6.1)
114
+ i18n (1.15.2)
115
+ concurrent-ruby (~> 1.0)
116
+ io-console (0.8.2)
117
+ irb (1.18.0)
118
+ pp (>= 0.6.0)
119
+ prism (>= 1.3.0)
120
+ rdoc (>= 4.0.0)
121
+ reline (>= 0.4.2)
122
+ json (2.20.0)
123
+ language_server-protocol (3.17.0.6)
124
+ lint_roller (1.1.0)
125
+ logger (1.7.0)
126
+ loofah (2.25.1)
127
+ crass (~> 1.0.2)
128
+ nokogiri (>= 1.12.0)
129
+ mail (2.9.1)
130
+ logger
131
+ mini_mime (>= 0.1.1)
132
+ net-imap
133
+ net-pop
134
+ net-smtp
135
+ marcel (1.2.1)
136
+ mini_mime (1.1.5)
137
+ minitest (5.27.0)
138
+ mocha (3.1.0)
139
+ ruby2_keywords (>= 0.0.5)
140
+ net-imap (0.6.4.1)
141
+ date
142
+ net-protocol
143
+ net-pop (0.1.2)
144
+ net-protocol
145
+ net-protocol (0.2.2)
146
+ timeout
147
+ net-smtp (0.5.1)
148
+ net-protocol
149
+ nio4r (2.7.5)
150
+ nokogiri (1.19.4-aarch64-linux-gnu)
151
+ racc (~> 1.4)
152
+ nokogiri (1.19.4-aarch64-linux-musl)
153
+ racc (~> 1.4)
154
+ nokogiri (1.19.4-arm-linux-gnu)
155
+ racc (~> 1.4)
156
+ nokogiri (1.19.4-arm-linux-musl)
157
+ racc (~> 1.4)
158
+ nokogiri (1.19.4-arm64-darwin)
159
+ racc (~> 1.4)
160
+ nokogiri (1.19.4-x86_64-darwin)
161
+ racc (~> 1.4)
162
+ nokogiri (1.19.4-x86_64-linux-gnu)
163
+ racc (~> 1.4)
164
+ nokogiri (1.19.4-x86_64-linux-musl)
165
+ racc (~> 1.4)
166
+ parallel (1.28.0)
167
+ parser (3.3.11.1)
168
+ ast (~> 2.4.1)
169
+ racc
170
+ pp (0.6.4)
171
+ prettyprint
172
+ prettyprint (0.2.0)
173
+ prism (1.9.0)
174
+ puma (8.0.2)
175
+ nio4r (~> 2.0)
176
+ raabro (1.4.0)
177
+ racc (1.8.1)
178
+ rack (3.2.6)
179
+ rack-session (2.1.2)
180
+ base64 (>= 0.1.0)
181
+ rack (>= 3.0.0)
182
+ rack-test (2.2.0)
183
+ rack (>= 1.3)
184
+ rackup (2.3.1)
185
+ rack (>= 3)
186
+ rails (8.1.3)
187
+ actioncable (= 8.1.3)
188
+ actionmailbox (= 8.1.3)
189
+ actionmailer (= 8.1.3)
190
+ actionpack (= 8.1.3)
191
+ actiontext (= 8.1.3)
192
+ actionview (= 8.1.3)
193
+ activejob (= 8.1.3)
194
+ activemodel (= 8.1.3)
195
+ activerecord (= 8.1.3)
196
+ activestorage (= 8.1.3)
197
+ activesupport (= 8.1.3)
198
+ bundler (>= 1.15.0)
199
+ railties (= 8.1.3)
200
+ rails-dom-testing (2.3.0)
201
+ activesupport (>= 5.0.0)
202
+ minitest
203
+ nokogiri (>= 1.6)
204
+ rails-html-sanitizer (1.7.0)
205
+ loofah (~> 2.25)
206
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
207
+ railties (8.1.3)
208
+ actionpack (= 8.1.3)
209
+ activesupport (= 8.1.3)
210
+ irb (~> 1.13)
211
+ rackup (>= 1.0.0)
212
+ rake (>= 12.2)
213
+ thor (~> 1.0, >= 1.2.2)
214
+ tsort (>= 0.2)
215
+ zeitwerk (~> 2.6)
216
+ rainbow (3.1.1)
217
+ rake (13.4.2)
218
+ rbs (4.0.3)
219
+ logger
220
+ prism (>= 1.6.0)
221
+ tsort
222
+ rdoc (8.0.0)
223
+ erb
224
+ prism (>= 1.6.0)
225
+ rbs (>= 4.0.0)
226
+ tsort
227
+ regexp_parser (2.12.0)
228
+ reline (0.6.3)
229
+ io-console (~> 0.5)
230
+ rubocop (1.88.2)
231
+ json (~> 2.3)
232
+ language_server-protocol (~> 3.17.0.2)
233
+ lint_roller (~> 1.1.0)
234
+ parallel (>= 1.10)
235
+ parser (>= 3.3.0.2)
236
+ rainbow (>= 2.2.2, < 4.0)
237
+ regexp_parser (>= 2.9.3, < 3.0)
238
+ rubocop-ast (>= 1.49.0, < 2.0)
239
+ ruby-progressbar (~> 1.7)
240
+ unicode-display_width (>= 2.4.0, < 4.0)
241
+ rubocop-ast (1.50.0)
242
+ parser (>= 3.3.7.2)
243
+ prism (~> 1.7)
244
+ rubocop-rails (2.35.5)
245
+ activesupport (>= 4.2.0)
246
+ lint_roller (~> 1.1)
247
+ rack (>= 1.1)
248
+ rubocop (>= 1.75.0, < 2.0)
249
+ rubocop-ast (>= 1.44.0, < 2.0)
250
+ ruby-progressbar (1.13.0)
251
+ ruby2_keywords (0.0.5)
252
+ securerandom (0.4.1)
253
+ solid_queue (1.4.0)
254
+ activejob (>= 7.1)
255
+ activerecord (>= 7.1)
256
+ concurrent-ruby (>= 1.3.1)
257
+ fugit (~> 1.11)
258
+ railties (>= 7.1)
259
+ thor (>= 1.3.1)
260
+ sqlite3 (2.9.5-aarch64-linux-gnu)
261
+ sqlite3 (2.9.5-aarch64-linux-musl)
262
+ sqlite3 (2.9.5-arm-linux-gnu)
263
+ sqlite3 (2.9.5-arm-linux-musl)
264
+ sqlite3 (2.9.5-arm64-darwin)
265
+ sqlite3 (2.9.5-x86_64-darwin)
266
+ sqlite3 (2.9.5-x86_64-linux-gnu)
267
+ sqlite3 (2.9.5-x86_64-linux-musl)
268
+ thor (1.5.0)
269
+ timeout (0.6.1)
270
+ tsort (0.2.0)
271
+ tzinfo (2.0.6)
272
+ concurrent-ruby (~> 1.0)
273
+ unicode-display_width (3.2.0)
274
+ unicode-emoji (~> 4.1)
275
+ unicode-emoji (4.2.0)
276
+ uri (1.1.1)
277
+ useragent (0.16.11)
278
+ websocket-driver (0.8.2)
279
+ base64
280
+ websocket-extensions (>= 0.1.0)
281
+ websocket-extensions (0.1.5)
282
+ zeitwerk (2.8.2)
283
+
284
+ PLATFORMS
285
+ aarch64-linux-gnu
286
+ aarch64-linux-musl
287
+ arm-linux-gnu
288
+ arm-linux-musl
289
+ arm64-darwin
290
+ x86_64-darwin
291
+ x86_64-linux-gnu
292
+ x86_64-linux-musl
293
+
294
+ DEPENDENCIES
295
+ appraisal (~> 2.5)
296
+ debug
297
+ minitest (~> 5.0)
298
+ mocha (>= 2.1)
299
+ parallel (~> 1.26)
300
+ puma (>= 6.0)
301
+ rails (>= 7.1, < 9.0)
302
+ rubocop (~> 1.75)
303
+ rubocop-rails (~> 2.30)
304
+ solid_queue_guard!
305
+ sqlite3 (~> 2.1)
306
+
307
+ BUNDLED WITH
308
+ 2.7.2
data/README.md CHANGED
@@ -67,7 +67,7 @@ One command. Actionable output. No Datadog required to get started.
67
67
 
68
68
  ## What it checks
69
69
 
70
- ### v0.1 — Configuration doctor (available now)
70
+ ### Configuration doctor
71
71
 
72
72
  Runs locally, in CI, or pre-deploy. **No extra infrastructure.**
73
73
 
@@ -83,8 +83,10 @@ Runs locally, in CI, or pre-deploy. **No extra infrastructure.**
83
83
  | **Env flags** | `SOLID_QUEUE_SKIP_RECURRING=true` in production |
84
84
  | **Heartbeats** | Default thresholds that may not fit your deploy |
85
85
  | **Puma plugin** | Solid Queue co-located with web in production |
86
+ | **Async supervisor** | `async` mode with thread/pool sizing risks |
87
+ | **Topology** | `queue.yml` worker and pool recommendations |
86
88
 
87
- ### v0.2+ — Runtime guards (roadmap)
89
+ ### Runtime guards
88
90
 
89
91
  | Check | Catches |
90
92
  | ----- | ------- |
@@ -93,6 +95,7 @@ Runs locally, in CI, or pre-deploy. **No extra infrastructure.**
93
95
  | **Dispatcher health** | Scheduled jobs never becoming ready |
94
96
  | **Blocked jobs** | Concurrency control silently holding jobs |
95
97
  | **Recurring staleness** | Cron tasks that stopped firing |
98
+ | **Puma plugin runtime** | Plugin enabled but no active Solid Queue processes |
96
99
  | **HTTP `/health`** | Kamal, ECS, K8s, UptimeRobot integration |
97
100
 
98
101
  ---
@@ -104,6 +107,7 @@ Runs locally, in CI, or pre-deploy. **No extra infrastructure.**
104
107
  ```bash
105
108
  bundle add solid_queue_guard
106
109
  bin/rails solid_queue_guard:install
110
+ bin/rails generate solid_queue_guard:install:ci # optional GitHub Actions workflow
107
111
  ```
108
112
 
109
113
  ### Run the doctor
@@ -138,7 +142,13 @@ Perfect for deploy pipelines:
138
142
  run: SOLID_QUEUE_GUARD_STRICT=1 bin/rails solid_queue_guard:doctor
139
143
  ```
140
144
 
141
- ### HTTP health (v0.2)
145
+ Or generate a workflow:
146
+
147
+ ```bash
148
+ bin/rails generate solid_queue_guard:install:ci
149
+ ```
150
+
151
+ ### HTTP health
142
152
 
143
153
  ```ruby
144
154
  # config/routes.rb
@@ -150,6 +160,20 @@ curl localhost:3000/solid_queue_guard/health
150
160
  # => { "status": "degraded", "queue_lag_seconds": 245, "warnings": [...] }
151
161
  ```
152
162
 
163
+ Optional token protection:
164
+
165
+ ```ruby
166
+ config.health_token = ENV["SOLID_QUEUE_GUARD_TOKEN"]
167
+ # curl -H "X-Solid-Queue-Guard-Token: $TOKEN" ...
168
+ ```
169
+
170
+ HTTP status policy (for Kamal, ECS, load balancers):
171
+
172
+ ```ruby
173
+ config.degraded_http_status = 207 # or :ok (200), 503, etc.
174
+ config.unhealthy_http_status = 503 # default
175
+ ```
176
+
153
177
  Works with **Kamal**, **Heroku**, **Fly.io**, **ECS/Fargate**, **Kubernetes**, **Better Stack**, **UptimeRobot**.
154
178
 
155
179
  ---
@@ -170,13 +194,46 @@ SolidQueueGuard.configure do |config|
170
194
  config.failed_jobs_threshold = 20
171
195
  config.stale_process_threshold = 5.minutes
172
196
 
173
- # config.health_token = ENV["SOLID_QUEUE_GUARD_TOKEN"] # v0.2
174
- # config.notify_with = [:rails_logger, :slack] # v0.3
197
+ # Per-check overrides (v0.6+)
198
+ config.disabled_checks = [:pidfile]
199
+ config.checks.queue_lag = { threshold: 10.minutes }
200
+ config.checks.failed_jobs = { threshold: 5, enabled: true }
201
+
202
+ # HTTP status policy (v0.8+)
203
+ # config.degraded_http_status = 207
204
+ # config.unhealthy_http_status = 503
205
+
206
+ # config.health_token = ENV["SOLID_QUEUE_GUARD_TOKEN"]
207
+ # config.integrate_rails_health = true
208
+ # config.notify_with = [:rails_logger, :slack, :datadog, :webhook]
209
+ # config.metrics_backends = [:statsd, :prometheus, :opentelemetry]
175
210
  end
176
211
  ```
177
212
 
178
213
  ---
179
214
 
215
+ ## Public API (v1.0+)
216
+
217
+ The following surface is **stable** until `2.0` and follows [semantic versioning](https://semver.org/):
218
+
219
+ | API | Description |
220
+ | --- | ----------- |
221
+ | `SolidQueueGuard.configure` | Block-style configuration |
222
+ | `SolidQueueGuard.config` | Current configuration object |
223
+ | `SolidQueueGuard.enabled?` | Whether checks run |
224
+ | `solid_queue_guard:doctor` | Config readiness report |
225
+ | `solid_queue_guard:health` | Runtime health report |
226
+ | `solid_queue_guard:report` | Full diagnostic report |
227
+ | `solid_queue_guard:install` | Initializer generator |
228
+ | `solid_queue_guard:install:ci` | GitHub Actions workflow generator |
229
+ | `mount SolidQueueGuard::Engine` | HTTP health endpoint |
230
+
231
+ Configuration attributes, rake tasks, and health JSON shape are public. Internal check classes and registry are `@api private`.
232
+
233
+ Breaking changes ship only in major versions (`2.0+`). Deprecations warn one minor version ahead.
234
+
235
+ ---
236
+
180
237
  ## solid_queue_guard vs Mission Control
181
238
 
182
239
  | | [Mission Control — Jobs](https://github.com/rails/mission_control-jobs) | solid_queue_guard |
@@ -185,9 +242,9 @@ end
185
242
  | **UI** | Dashboard | CLI + JSON + health endpoint |
186
243
  | **Retry / discard** | Yes | No (use Mission Control) |
187
244
  | **Config doctor** | No | Yes |
188
- | **Queue lag alerts** | No | Yes (v0.2) |
245
+ | **Queue lag alerts** | No | Yes |
189
246
  | **Pre-deploy checks** | No | Yes |
190
- | **Recurring job guard** | Manual inspection | Automatic (v0.2) |
247
+ | **Recurring job guard** | Manual inspection | Automatic |
191
248
 
192
249
  **Use both.** They solve different problems.
193
250
 
@@ -195,13 +252,17 @@ end
195
252
 
196
253
  ## Roadmap
197
254
 
198
- | Version | Ships |
199
- | ------- | ----- |
200
- | **v0.1** | `doctor` — config checks, CI integration, install generator |
201
- | **v0.2** | Runtime health, queue lag, dispatcher/blocked jobs, HTTP endpoint |
202
- | **v0.3** | Slack, Datadog, webhook notifications |
203
- | **v0.4** | StatsD, Prometheus, OpenTelemetry metrics |
204
- | **v0.5** | Auto-recommendations for `queue.yml` topology |
255
+ | Version | Ships | Status |
256
+ | ------- | ----- | ------ |
257
+ | **v0.1** | `doctor` — config checks, CI integration, install generator | ✅ Released |
258
+ | **v0.2** | Runtime health, queue lag, dispatcher/blocked jobs, HTTP endpoint | ✅ Released |
259
+ | **v0.3** | Slack, Datadog, webhook notifications | ✅ Released |
260
+ | **v0.4** | StatsD, Prometheus, OpenTelemetry metrics | ✅ Released |
261
+ | **v0.5** | Auto-recommendations for `queue.yml` topology | ✅ Released |
262
+ | **v0.6** | Per-check configuration (`disabled_checks`, `config.checks`) | ✅ Released |
263
+ | **v0.7** | Puma plugin runtime check, async supervisor awareness | ✅ Released |
264
+ | **v0.8** | HTTP status policy, `install:ci` generator | ✅ Released |
265
+ | **v1.0** | Stable public API, strict semver | ✅ Released |
205
266
 
206
267
  ---
207
268
 
@@ -209,6 +270,8 @@ end
209
270
 
210
271
  | Gem version | Ruby | Rails |
211
272
  | ----------- | ---- | ----- |
273
+ | 1.0.x | 3.1+ | 7.1, 7.2, 8.0 |
274
+ | 0.5.x | 3.1+ | 7.1, 7.2, 8.0 |
212
275
  | 0.1.x | 3.1+ | 7.1, 7.2, 8.0 |
213
276
 
214
277
  ## Requirements
@@ -232,6 +295,8 @@ bundle exec appraisal install
232
295
  bundle exec appraisal rake test
233
296
  ```
234
297
 
298
+ Release a new version by pushing a `v*` tag after CI passes (Trusted Publishing on RubyGems).
299
+
235
300
  ---
236
301
 
237
302
  ## Contributing
@@ -2,5 +2,6 @@
2
2
 
3
3
  module SolidQueueGuard
4
4
  class ApplicationController < ActionController::Base
5
+ protect_from_forgery with: :null_session
5
6
  end
6
7
  end
@@ -2,8 +2,29 @@
2
2
 
3
3
  module SolidQueueGuard
4
4
  class HealthController < ApplicationController
5
+ before_action :authenticate_token!
6
+
5
7
  def show
6
- render json: { status: 'not_implemented', message: 'HTTP health checks ship in v0.2' }, status: :not_implemented
8
+ payload = Health::Cache.fetch
9
+ status_code = http_status_for(payload[:status])
10
+
11
+ render json: payload, status: status_code
12
+ end
13
+
14
+ private
15
+
16
+ def authenticate_token!
17
+ token = SolidQueueGuard.config.health_token
18
+ return if token.blank?
19
+
20
+ provided = request.headers['X-Solid-Queue-Guard-Token'].presence || params[:token]
21
+ return if ActiveSupport::SecurityUtils.secure_compare(provided.to_s, token.to_s)
22
+
23
+ render json: { status: 'unauthorized' }, status: :unauthorized
24
+ end
25
+
26
+ def http_status_for(status)
27
+ HttpStatusPolicy.for_report_status(status)
7
28
  end
8
29
  end
9
30
  end
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Adds a GitHub Actions workflow that runs `solid_queue_guard:doctor` with strict mode.
3
+
4
+ Example:
5
+ bin/rails generate solid_queue_guard:install:ci
6
+
7
+ This will create:
8
+
9
+ .github/workflows/solid_queue_guard.yml