patient_http-sidekiq 1.1.0 → 1.1.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b97f976999ea59ac067153a7698579accb7e7a9941171adbb31e1270ff044fc8
4
- data.tar.gz: bf45c48c1afaae62826c66f8a2a8f5cd82379b40edc0c9d34faad1c856cfbcd2
3
+ metadata.gz: 25eda5f2b6779bc4c2208a6e57bf50bb98277706c97d7ff6bacf7368c369c842
4
+ data.tar.gz: b110134e0fbb6a9ad8cee382c81d809267ebe0d5eb730a93fd10ce5871de2c1e
5
5
  SHA512:
6
- metadata.gz: bff1df1ca4265615ec56aedce59ef87a08f70344f31324e432e231d114c7b04139424a29cf510d8aac6cc0dad2643149cf1f4b17c194066e3fe13deea4a8989b
7
- data.tar.gz: 2fb165723aecdd602a638f81a3a2804ff3951e1b3db74c4dc1afbc5a6e32420adc9728fbe06d503bd424616fd5c665faf8cb93b74bbcde2b2193681d0c6f3651
6
+ metadata.gz: 62a51fd65f0d68bbe3223417bd663468ab4fe120704f6a4ddf32f6f220d057365588058061baa41c63aa33c3221dcba16105e85a0d5dba0c2c2e1dd365144626
7
+ data.tar.gz: 28550b4fe12f889a9fa28e0e9bd25737693994940cba28d385207870909f019c88d69acc5248a55af302054f5352db6b08780772457b7617608f1677a3ad16c0
data/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## 1.1.2
8
+
9
+ ### Fixed
10
+
11
+ - The Web UI stylesheet now loads on Sidekiq 7.x. The `style_tag` helper returns the link tag on Sidekiq 7 but adds it to the page head on Sidekiq 8; the view now handles both.
12
+ - The Web UI stylesheet now uses CSS variables that the Sidekiq 8 web UI actually defines (`--color-primary`, `--color-text`, ...), with static fallback values for Sidekiq 7.x.
13
+
14
+ ## 1.1.1
15
+
16
+ ### Fixed
17
+
18
+ - The Sidekiq Web UI extension now registers correctly on Sidekiq 7.3. It previously raised `NoMethodError: undefined method 'register_extension' for class Sidekiq::Web` because that method only exists in Sidekiq 8.
19
+ - The Web UI dashboard page now renders on Sidekiq versions before 8.1. Those versions resolve view files as `*.erb` instead of `*.html.erb`, so the template is now rendered from a string.
20
+ - Requiring the Web UI on Sidekiq versions before 7.3 now raises a `LoadError` with a clear message instead of an obscure error.
21
+
22
+ ### Added
23
+
24
+ - `require "patient_http/sidekiq/web"` can now be used to load the Web UI extension, matching the `require "sidekiq/web"` convention. The previous `patient_http/sidekiq/web_ui` path still works.
25
+
7
26
  ## 1.1.0
8
27
 
9
28
  ### Changed
data/README.md CHANGED
@@ -485,12 +485,11 @@ See the [Configuration](lib/patient_http/sidekiq/configuration.rb) class for all
485
485
 
486
486
  ### Web UI
487
487
 
488
- If you're using Sidekiq's Web UI, you can add a tab with the async HTTP processor statistics. The extension auto-registers when `Sidekiq::Web` is defined:
488
+ If you're using Sidekiq's Web UI, you can add a tab with the async HTTP processor statistics. The Web UI tab requires Sidekiq 7.3 or later.
489
489
 
490
490
  ```ruby
491
491
  # config/routes.rb (Rails)
492
- require "sidekiq/web"
493
- require "patient_http-sidekiq"
492
+ require "patient_http/sidekiq/web"
494
493
 
495
494
  mount Sidekiq::Web => "/sidekiq"
496
495
  ```
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.1.2
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file exists so that the require path for the web UI can match the
4
+ # file path in sidekiq itself: `require "patient_http/sidekiq/web"`
5
+
6
+ require_relative "web_ui"
@@ -1,18 +1,29 @@
1
1
  /* PatientHttp Dashboard Stylesheet */
2
2
 
3
3
  .patient-http-dashboard {
4
- --patient-http-primary: var(--color-brand);
5
- --patient-http-success: var(--color-ok);
6
- --patient-http-error: var(--color-err);
7
- --patient-http-warning: var(--color-warn);
8
- --patient-http-bg: var(--color-bg);
9
- --patient-http-text: var(--color-fg);
10
- --patient-http-border: var(--color-border);
11
- --patient-http-subtle: var(--color-subtle);
4
+ /* The --color-* variables come from the Sidekiq 8 web UI stylesheet. The
5
+ fallback values are for Sidekiq 7.x, which defines no CSS variables.
6
+ Status colors are static because Sidekiq 8 only defines pastel label
7
+ backgrounds, which are unreadable as text colors. */
8
+ --patient-http-primary: var(--color-primary, #b91d47);
9
+ --patient-http-success: #28a745;
10
+ --patient-http-error: #dc3545;
11
+ --patient-http-warning: #b45309;
12
+ --patient-http-bg: var(--color-bg, transparent);
13
+ --patient-http-text: var(--color-text, inherit);
14
+ --patient-http-border: var(--color-border, #dee2e6);
15
+ --patient-http-subtle: var(--color-text-light, #757575);
16
+ --patient-http-card-bg: var(--color-elevated, transparent);
17
+ --patient-http-card-hover: var(--color-selected, transparent);
18
+
19
+ /* Reset the base font size because the Bootstrap CSS in the Sidekiq 7.x
20
+ web UI sets a 10px root font size. Font sizes below are in em so they
21
+ scale from this base on every Sidekiq version. */
22
+ font-size: var(--font-size, 16px);
12
23
  }
13
24
 
14
25
  .patient-http-dashboard .section {
15
- margin-top: 1.5rem;
26
+ margin-top: 24px;
16
27
  background: var(--patient-http-bg);
17
28
  }
18
29
 
@@ -20,7 +31,7 @@
20
31
  display: flex;
21
32
  justify-content: space-between;
22
33
  align-items: center;
23
- margin-bottom: var(--space-lg, 1.5rem);
34
+ margin-bottom: 24px;
24
35
  }
25
36
 
26
37
  .patient-http-dashboard .header-with-button h2 {
@@ -32,30 +43,30 @@
32
43
  }
33
44
 
34
45
  .patient-http-dashboard .clear-stats-form .btn {
35
- font-size: 0.875rem;
36
- padding: 0.5rem 1rem;
46
+ font-size: 0.875em;
47
+ padding: 8px 16px;
37
48
  }
38
49
 
39
50
  .patient-http-dashboard h2 {
40
- margin: 0 0 var(--space-lg, 1.5rem) 0;
51
+ margin: 0 0 24px 0;
41
52
  color: var(--patient-http-text);
42
- font-size: 1.75rem;
53
+ font-size: 1.75em;
43
54
  font-weight: 600;
44
55
  letter-spacing: -0.015em;
45
56
  }
46
57
 
47
58
  .patient-http-dashboard h3 {
48
- margin: var(--space-xl, 2rem) 0 var(--space-lg, 1.5rem) 0;
59
+ margin: 32px 0 24px 0;
49
60
  color: var(--patient-http-text);
50
- font-size: 1.25rem;
61
+ font-size: 1.25em;
51
62
  font-weight: 600;
52
63
  letter-spacing: -0.01em;
53
64
  }
54
65
 
55
66
  .patient-http-dashboard h4 {
56
- margin: var(--space-md, 1rem) 0 var(--space-sm, 0.75rem) 0;
67
+ margin: 16px 0 12px 0;
57
68
  color: var(--patient-http-text);
58
- font-size: 1rem;
69
+ font-size: 1em;
59
70
  font-weight: 600;
60
71
  }
61
72
 
@@ -63,30 +74,30 @@
63
74
  .stats-grid {
64
75
  display: grid;
65
76
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
66
- gap: var(--space-lg, 1.5rem);
67
- margin-bottom: var(--space-xl, 2rem);
77
+ gap: 24px;
78
+ margin-bottom: 32px;
68
79
  }
69
80
 
70
81
  .stat-card {
71
- padding: var(--space-lg, 1.5rem);
72
- background: var(--color-card-bg, rgb(255 255 255));
82
+ padding: 24px;
83
+ background: var(--patient-http-card-bg);
73
84
  border: 1px solid var(--patient-http-border);
74
- border-radius: 0.375rem;
85
+ border-radius: 6px;
75
86
  display: flex;
76
87
  flex-direction: column;
77
88
  justify-content: space-between;
78
89
  }
79
90
 
80
91
  .stat-label {
81
- font-size: 0.875rem;
82
- color: var(--color-subtle, rgb(128 128 128));
92
+ font-size: 0.875em;
93
+ color: var(--patient-http-subtle);
83
94
  font-weight: 500;
84
- margin-bottom: var(--space-sm, 0.75rem);
95
+ margin-bottom: 12px;
85
96
  letter-spacing: 0.02em;
86
97
  }
87
98
 
88
99
  .stat-value {
89
- font-size: 2rem;
100
+ font-size: 2em;
90
101
  font-weight: 700;
91
102
  color: var(--patient-http-primary);
92
103
  letter-spacing: -0.02em;
@@ -99,75 +110,75 @@
99
110
 
100
111
  /* Capacity Section */
101
112
  .capacity-section {
102
- margin: var(--space-xl, 2rem) 0;
103
- padding: var(--space-lg, 1.5rem);
104
- background: var(--color-card-bg, rgb(255 255 255));
113
+ margin: 32px 0;
114
+ padding: 24px;
115
+ background: var(--patient-http-card-bg);
105
116
  border: 1px solid var(--patient-http-border);
106
- border-radius: 0.375rem;
117
+ border-radius: 6px;
107
118
  }
108
119
 
109
120
  .capacity-cards {
110
121
  display: grid;
111
122
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
112
- gap: var(--space-lg, 1.5rem);
113
- margin-bottom: var(--space-xl, 2rem);
123
+ gap: 24px;
124
+ margin-bottom: 32px;
114
125
  }
115
126
 
116
127
  .capacity-card {
117
- padding: var(--space-md, 1rem);
118
- background: var(--patient-http-bg, rgb(255 255 255));
128
+ padding: 16px;
129
+ background: var(--patient-http-card-bg);
119
130
  border: 1px solid var(--patient-http-border);
120
- border-radius: 0.25rem;
131
+ border-radius: 4px;
121
132
  text-align: center;
122
133
  }
123
134
 
124
135
  .capacity-label {
125
- font-size: 0.875rem;
126
- color: var(--color-subtle, rgb(128 128 128));
136
+ font-size: 0.875em;
137
+ color: var(--patient-http-subtle);
127
138
  font-weight: 500;
128
- margin-bottom: 0.5rem;
139
+ margin-bottom: 8px;
129
140
  display: block;
130
141
  }
131
142
 
132
143
  .capacity-value {
133
144
  display: block;
134
- font-size: 1.75rem;
145
+ font-size: 1.75em;
135
146
  font-weight: 700;
136
147
  color: var(--patient-http-primary);
137
148
  line-height: 1;
138
- margin-bottom: 0.25rem;
149
+ margin-bottom: 4px;
139
150
  }
140
151
 
141
152
  .capacity-unit {
142
- font-size: 0.75rem;
143
- color: var(--color-subtle, rgb(128 128 128));
153
+ font-size: 0.75em;
154
+ color: var(--patient-http-subtle);
144
155
  text-transform: uppercase;
145
156
  letter-spacing: 0.05em;
146
157
  }
147
158
 
148
159
  /* Process Breakdown Table */
149
160
  .process-breakdown {
150
- margin-top: var(--space-lg, 1.5rem);
161
+ margin-top: 24px;
151
162
  }
152
163
 
153
164
  /* Breakdown Sections (HTTP Status Codes, Error Types) */
154
165
  .breakdown-section {
155
- margin: var(--space-xl, 2rem) 0;
156
- padding: var(--space-lg, 1.5rem);
157
- background: var(--color-card-bg, rgb(255 255 255));
166
+ margin: 32px 0;
167
+ padding: 24px;
168
+ background: var(--patient-http-card-bg);
158
169
  border: 1px solid var(--patient-http-border);
159
- border-radius: 0.375rem;
170
+ border-radius: 6px;
160
171
  }
161
172
 
162
173
  .breakdown-section h3 {
163
- margin: 0 0 var(--space-lg, 1.5rem) 0;
174
+ margin: 0 0 24px 0;
164
175
  }
165
176
 
166
177
  /* Table Styling */
167
178
  .patient-http-dashboard .table {
168
179
  width: 100%;
169
180
  border-collapse: collapse;
170
- margin-top: var(--space-md, 1rem);
181
+ margin-top: 16px;
171
182
  }
172
183
 
173
184
  .patient-http-dashboard .table thead {
@@ -176,16 +187,16 @@
176
187
  }
177
188
 
178
189
  .patient-http-dashboard .table th {
179
- padding: var(--space-md, 1rem);
190
+ padding: 16px;
180
191
  text-align: left;
181
192
  font-weight: 600;
182
193
  color: var(--patient-http-text);
183
- font-size: 0.875rem;
194
+ font-size: 0.875em;
184
195
  letter-spacing: 0.01em;
185
196
  }
186
197
 
187
198
  .patient-http-dashboard .table td {
188
- padding: var(--space-md, 1rem);
199
+ padding: 16px;
189
200
  border-bottom: 1px solid var(--patient-http-border);
190
201
  color: var(--patient-http-text);
191
202
  }
@@ -196,7 +207,7 @@
196
207
 
197
208
  .patient-http-dashboard .table .empty-state {
198
209
  text-align: center;
199
- color: var(--color-subtle, rgb(128 128 128));
210
+ color: var(--patient-http-subtle);
200
211
  font-style: italic;
201
212
  }
202
213
 
@@ -211,15 +222,15 @@
211
222
  }
212
223
 
213
224
  .patient-http-dashboard h2 {
214
- font-size: 1.5rem;
225
+ font-size: 1.5em;
215
226
  }
216
227
 
217
228
  .patient-http-dashboard h3 {
218
- font-size: 1.125rem;
229
+ font-size: 1.125em;
219
230
  }
220
231
 
221
232
  .stat-value {
222
- font-size: 1.5rem;
233
+ font-size: 1.5em;
223
234
  }
224
235
  }
225
236
 
@@ -233,17 +244,10 @@
233
244
  }
234
245
 
235
246
  .capacity-value {
236
- font-size: 1.5rem;
247
+ font-size: 1.5em;
237
248
  }
238
249
  }
239
250
 
240
- /* Dark Mode Support (via CSS variables) */
241
- @media (prefers-color-scheme: dark) {
242
- .stat-card {
243
- background: var(--color-card-bg);
244
- }
245
-
246
- .stat-card:hover {
247
- background: var(--color-card-hover);
248
- }
251
+ .stat-card:hover {
252
+ background: var(--patient-http-card-hover);
249
253
  }
@@ -138,5 +138,7 @@
138
138
  </div>
139
139
  </div>
140
140
 
141
- <%# Note: style tag does not use the "=" to send output %>
142
- <% style_tag("patient-http/css/patient_http.css") %>
141
+ <%# Sidekiq 8 adds the link tag to the page head and returns an Array;
142
+ Sidekiq 7 returns the link tag as a String that must be output in place. %>
143
+ <% stylesheet = style_tag("patient-http/css/patient_http.css") %>
144
+ <%= stylesheet if stylesheet.is_a?(String) %>
@@ -1,5 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "sidekiq/version"
4
+
5
+ # Sidekiq 7.3 introduced the web extension API used here (register with
6
+ # keyword arguments); older versions cannot mount the tab or assets. Check
7
+ # before loading sidekiq/web, which can itself fail to load on old versions.
8
+ if Gem::Version.new(::Sidekiq::VERSION) < Gem::Version.new("7.3")
9
+ raise LoadError.new("patient_http/sidekiq/web requires sidekiq >= 7.3 (you have #{::Sidekiq::VERSION})")
10
+ end
11
+
3
12
  require "sidekiq/web"
4
13
 
5
14
  module PatientHttp
@@ -12,6 +21,13 @@ module PatientHttp
12
21
  VIEWS = File.join(ROOT, "views")
13
22
 
14
23
  class << self
24
+ # Sidekiq resolves symbol view names to different file names depending
25
+ # on the version (*.erb before 8.1, *.html.erb from 8.1 on), so the
26
+ # template is rendered from a string instead.
27
+ def template
28
+ @template ||= File.read(File.join(VIEWS, "patient_http.html.erb"))
29
+ end
30
+
15
31
  # This method is called by Sidekiq::Web when registering the extension
16
32
  def registered(app)
17
33
  # GET route for the main PatientHttp dashboard page
@@ -31,7 +47,7 @@ module PatientHttp
31
47
  current_inflight = processes.values.sum { |data| data[:inflight] }
32
48
  utilization = (max_capacity > 0) ? (current_inflight.to_f / max_capacity * 100).round(1) : 0
33
49
 
34
- erb(:patient_http, views: PatientHttp::Sidekiq::WebUI::VIEWS, locals: {
50
+ erb(PatientHttp::Sidekiq::WebUI.template, locals: {
35
51
  totals: totals,
36
52
  total_requests: total_requests,
37
53
  avg_duration: avg_duration,
@@ -52,18 +68,26 @@ module PatientHttp
52
68
  end
53
69
  end
54
70
 
55
- # Auto-register the web UI extension if Sidekiq::Web is available
56
- # This is called after require "sidekiq/web" in the application
57
- if defined?(::Sidekiq::Web)
71
+ register_options = {
72
+ name: "patient-http",
73
+ tab: "patient_http_tab",
74
+ index: "patient-http",
75
+ root_dir: PatientHttp::Sidekiq::WebUI::ROOT,
76
+ asset_paths: ["css", "js"]
77
+ }
78
+
79
+ if ::Sidekiq::Web.respond_to?(:configure)
58
80
  ::Sidekiq::Web.configure do |config|
59
- config.register_extension(
60
- PatientHttp::Sidekiq::WebUI,
61
- name: "patient-http",
62
- tab: "patient_http_tab",
63
- index: "patient-http",
64
- root_dir: PatientHttp::Sidekiq::WebUI::ROOT,
65
- asset_paths: ["css", "js"]
66
- )
81
+ if config.respond_to?(:register_extension)
82
+ # Sidekiq 8.x yields a Sidekiq::Web::Config object
83
+ config.register_extension(PatientHttp::Sidekiq::WebUI, **register_options)
84
+ else
85
+ # Sidekiq 7.3.5+ yields the Sidekiq::Web class, which only has register
86
+ config.register(PatientHttp::Sidekiq::WebUI, **register_options)
87
+ end
67
88
  end
89
+ else
90
+ # Sidekiq 7.3.0 - 7.3.4 has no Sidekiq::Web.configure
91
+ ::Sidekiq::Web.register(PatientHttp::Sidekiq::WebUI, **register_options)
68
92
  end
69
93
  end
@@ -41,6 +41,4 @@ Gem::Specification.new do |spec|
41
41
 
42
42
  spec.add_dependency "sidekiq", ">= 7.0"
43
43
  spec.add_dependency "patient_http", ">= 1.3.0"
44
-
45
- spec.add_development_dependency "bundler"
46
44
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patient_http-sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
@@ -37,20 +37,6 @@ dependencies:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: 1.3.0
40
- - !ruby/object:Gem::Dependency
41
- name: bundler
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: '0'
47
- type: :development
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
40
  description: This gem provides a mechanism to offload long-running HTTP requests from
55
41
  Sidekiq workers to a dedicated async I/O processor running in the same process,
56
42
  freeing the worker thread immediately while the HTTP request is in flight.
@@ -78,6 +64,7 @@ files:
78
64
  - lib/patient_http/sidekiq/task_handler.rb
79
65
  - lib/patient_http/sidekiq/task_monitor.rb
80
66
  - lib/patient_http/sidekiq/task_monitor_thread.rb
67
+ - lib/patient_http/sidekiq/web.rb
81
68
  - lib/patient_http/sidekiq/web_ui.rb
82
69
  - lib/patient_http/sidekiq/web_ui/assets/patient-http/css/patient_http.css
83
70
  - lib/patient_http/sidekiq/web_ui/locales/ar.yml
@@ -133,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
120
  - !ruby/object:Gem::Version
134
121
  version: '0'
135
122
  requirements: []
136
- rubygems_version: 4.0.3
123
+ rubygems_version: 3.6.9
137
124
  specification_version: 4
138
125
  summary: Offload long-running HTTP requests from Sidekiq workers to a dedicated async
139
126
  I/O processor