solid_queue_monitor 0.2.0 → 0.3.1
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 +4 -4
- data/README.md +25 -11
- data/Rakefile +8 -8
- data/app/controllers/solid_queue_monitor/application_controller.rb +25 -0
- data/app/controllers/solid_queue_monitor/base_controller.rb +70 -67
- data/app/controllers/solid_queue_monitor/failed_jobs_controller.rb +8 -7
- data/app/controllers/solid_queue_monitor/in_progress_jobs_controller.rb +16 -10
- data/app/controllers/solid_queue_monitor/overview_controller.rb +13 -12
- data/app/controllers/solid_queue_monitor/queues_controller.rb +4 -2
- data/app/controllers/solid_queue_monitor/ready_jobs_controller.rb +8 -7
- data/app/controllers/solid_queue_monitor/recurring_jobs_controller.rb +7 -6
- data/app/controllers/solid_queue_monitor/scheduled_jobs_controller.rb +8 -7
- data/app/presenters/solid_queue_monitor/base_presenter.rb +70 -53
- data/app/presenters/solid_queue_monitor/failed_jobs_presenter.rb +51 -41
- data/app/presenters/solid_queue_monitor/in_progress_jobs_presenter.rb +13 -2
- data/app/presenters/solid_queue_monitor/jobs_presenter.rb +18 -9
- data/app/presenters/solid_queue_monitor/queues_presenter.rb +5 -5
- data/app/presenters/solid_queue_monitor/ready_jobs_presenter.rb +10 -2
- data/app/presenters/solid_queue_monitor/recurring_jobs_presenter.rb +5 -2
- data/app/presenters/solid_queue_monitor/scheduled_jobs_presenter.rb +15 -9
- data/app/presenters/solid_queue_monitor/stats_presenter.rb +3 -1
- data/app/services/solid_queue_monitor/authentication_service.rb +7 -5
- data/app/services/solid_queue_monitor/execute_job_service.rb +3 -1
- data/app/services/solid_queue_monitor/failed_job_service.rb +38 -36
- data/app/services/solid_queue_monitor/html_generator.rb +5 -2
- data/app/services/solid_queue_monitor/pagination_service.rb +3 -1
- data/app/services/solid_queue_monitor/stats_calculator.rb +3 -1
- data/app/services/solid_queue_monitor/status_calculator.rb +4 -1
- data/app/services/solid_queue_monitor/stylesheet_generator.rb +68 -22
- data/config/initializers/solid_queue_monitor.rb +3 -1
- data/config/routes.rb +6 -4
- data/lib/generators/solid_queue_monitor/install_generator.rb +7 -5
- data/lib/generators/solid_queue_monitor/templates/initializer.rb +3 -1
- data/lib/solid_queue_monitor/engine.rb +5 -3
- data/lib/solid_queue_monitor/version.rb +2 -2
- data/lib/solid_queue_monitor.rb +9 -13
- data/lib/tasks/app.rake +42 -40
- metadata +9 -148
- data/app/controllers/solid_queue_monitor/monitor_controller.rb +0 -318
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidQueueMonitor
|
2
4
|
class ScheduledJobsPresenter < BasePresenter
|
3
|
-
|
4
5
|
include Rails.application.routes.url_helpers
|
5
6
|
include SolidQueueMonitor::Engine.routes.url_helpers
|
6
7
|
|
@@ -31,13 +32,18 @@ module SolidQueueMonitor
|
|
31
32
|
<input type="text" name="queue_name" id="queue_name" value="#{@filters[:queue_name]}" placeholder="Filter by queue">
|
32
33
|
</div>
|
33
34
|
|
35
|
+
<div class="filter-group">
|
36
|
+
<label for="arguments">Arguments:</label>
|
37
|
+
<input type="text" name="arguments" id="arguments" value="#{@filters[:arguments]}" placeholder="Filter by arguments">
|
38
|
+
</div>
|
39
|
+
|
34
40
|
<div class="filter-actions">
|
35
41
|
<button type="submit" class="filter-button">Apply Filters</button>
|
36
42
|
<a href="#{scheduled_jobs_path}" class="reset-button">Reset</a>
|
37
43
|
</div>
|
38
44
|
</form>
|
39
45
|
</div>
|
40
|
-
|
46
|
+
|
41
47
|
<div class="bulk-actions-bar">
|
42
48
|
<button type="button" class="action-button execute-button" id="execute-selected-top" disabled>Execute Selected</button>
|
43
49
|
</div>
|
@@ -55,7 +61,7 @@ module SolidQueueMonitor
|
|
55
61
|
const jobCheckboxes = document.getElementsByName('job_ids[]');
|
56
62
|
const executeButton = document.getElementById('execute-selected-top');
|
57
63
|
const form = document.getElementById('scheduled-jobs-form');
|
58
|
-
|
64
|
+
#{' '}
|
59
65
|
selectAllCheckbox.addEventListener('change', function() {
|
60
66
|
jobCheckboxes.forEach(checkbox => checkbox.checked = this.checked);
|
61
67
|
updateExecuteButton();
|
@@ -67,12 +73,12 @@ module SolidQueueMonitor
|
|
67
73
|
updateExecuteButton();
|
68
74
|
});
|
69
75
|
});
|
70
|
-
|
76
|
+
#{' '}
|
71
77
|
// Add event listener for the execute button
|
72
78
|
executeButton.addEventListener('click', function() {
|
73
79
|
const selectedIds = Array.from(document.querySelectorAll('input[name="job_ids[]"]:checked')).map(cb => cb.value);
|
74
80
|
if (selectedIds.length === 0) return;
|
75
|
-
|
81
|
+
#{' '}
|
76
82
|
// Add selected IDs as hidden inputs
|
77
83
|
selectedIds.forEach(id => {
|
78
84
|
const input = document.createElement('input');
|
@@ -81,16 +87,16 @@ module SolidQueueMonitor
|
|
81
87
|
input.value = id;
|
82
88
|
form.appendChild(input);
|
83
89
|
});
|
84
|
-
|
90
|
+
#{' '}
|
85
91
|
form.submit();
|
86
92
|
});
|
87
|
-
|
93
|
+
#{' '}
|
88
94
|
function updateExecuteButton() {
|
89
95
|
const checkboxes = document.getElementsByName('job_ids[]');
|
90
96
|
const checked = Array.from(checkboxes).some(cb => cb.checked);
|
91
97
|
executeButton.disabled = !checked;
|
92
98
|
}
|
93
|
-
|
99
|
+
#{' '}
|
94
100
|
// Initialize button state
|
95
101
|
updateExecuteButton();
|
96
102
|
});
|
@@ -134,4 +140,4 @@ module SolidQueueMonitor
|
|
134
140
|
HTML
|
135
141
|
end
|
136
142
|
end
|
137
|
-
end
|
143
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidQueueMonitor
|
2
4
|
class AuthenticationService
|
3
5
|
def self.authenticate(username, password)
|
4
6
|
return true unless SolidQueueMonitor.authentication_enabled
|
5
|
-
|
6
|
-
username == SolidQueueMonitor.username &&
|
7
|
-
|
7
|
+
|
8
|
+
username == SolidQueueMonitor.username &&
|
9
|
+
password == SolidQueueMonitor.password
|
8
10
|
end
|
9
|
-
|
11
|
+
|
10
12
|
def self.authentication_required?
|
11
13
|
SolidQueueMonitor.authentication_enabled
|
12
14
|
end
|
13
15
|
end
|
14
|
-
end
|
16
|
+
end
|
@@ -1,47 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidQueueMonitor
|
2
4
|
class FailedJobService
|
3
5
|
def retry_job(failed_execution_id)
|
4
6
|
failed_execution = SolidQueue::FailedExecution.find_by(id: failed_execution_id)
|
5
|
-
return { success: false, message:
|
6
|
-
|
7
|
+
return { success: false, message: 'Failed job not found' } unless failed_execution
|
8
|
+
|
7
9
|
job = failed_execution.job
|
8
|
-
return { success: false, message:
|
9
|
-
|
10
|
+
return { success: false, message: 'Associated job not found' } unless job
|
11
|
+
|
10
12
|
ActiveRecord::Base.transaction do
|
11
13
|
SolidQueue::ReadyExecution.create!(
|
12
14
|
job_id: job.id,
|
13
15
|
queue_name: get_queue_name(failed_execution, job),
|
14
16
|
priority: job.priority
|
15
17
|
)
|
16
|
-
|
18
|
+
|
17
19
|
failed_execution.destroy!
|
18
20
|
end
|
19
|
-
|
20
|
-
{ success: true, message:
|
21
|
+
|
22
|
+
{ success: true, message: 'Job moved to ready queue for retry' }
|
21
23
|
end
|
22
|
-
|
24
|
+
|
23
25
|
def discard_job(failed_execution_id)
|
24
26
|
failed_execution = SolidQueue::FailedExecution.find_by(id: failed_execution_id)
|
25
|
-
return { success: false, message:
|
26
|
-
|
27
|
+
return { success: false, message: 'Failed job not found' } unless failed_execution
|
28
|
+
|
27
29
|
job = failed_execution.job
|
28
|
-
return { success: false, message:
|
29
|
-
|
30
|
+
return { success: false, message: 'Associated job not found' } unless job
|
31
|
+
|
30
32
|
ActiveRecord::Base.transaction do
|
31
33
|
job.update!(finished_at: Time.current)
|
32
|
-
|
34
|
+
|
33
35
|
failed_execution.destroy!
|
34
36
|
end
|
35
|
-
|
36
|
-
{ success: true, message:
|
37
|
+
|
38
|
+
{ success: true, message: 'Job has been discarded' }
|
37
39
|
end
|
38
|
-
|
40
|
+
|
39
41
|
def retry_all(job_ids)
|
40
|
-
return { success: false, message:
|
41
|
-
|
42
|
+
return { success: false, message: 'No jobs selected' } if job_ids.blank?
|
43
|
+
|
42
44
|
success_count = 0
|
43
45
|
failed_count = 0
|
44
|
-
|
46
|
+
|
45
47
|
job_ids.each do |id|
|
46
48
|
result = retry_job(id)
|
47
49
|
if result[:success]
|
@@ -50,22 +52,22 @@ module SolidQueueMonitor
|
|
50
52
|
failed_count += 1
|
51
53
|
end
|
52
54
|
end
|
53
|
-
|
54
|
-
if success_count
|
55
|
-
{ success: true, message:
|
56
|
-
elsif success_count
|
55
|
+
|
56
|
+
if success_count.positive? && failed_count.zero?
|
57
|
+
{ success: true, message: 'All selected jobs have been queued for retry' }
|
58
|
+
elsif success_count.positive? && failed_count.positive?
|
57
59
|
{ success: true, message: "#{success_count} jobs queued for retry, #{failed_count} failed" }
|
58
60
|
else
|
59
|
-
{ success: false, message:
|
61
|
+
{ success: false, message: 'Failed to retry jobs' }
|
60
62
|
end
|
61
63
|
end
|
62
|
-
|
64
|
+
|
63
65
|
def discard_all(job_ids)
|
64
|
-
return { success: false, message:
|
65
|
-
|
66
|
+
return { success: false, message: 'No jobs selected' } if job_ids.blank?
|
67
|
+
|
66
68
|
success_count = 0
|
67
69
|
failed_count = 0
|
68
|
-
|
70
|
+
|
69
71
|
job_ids.each do |id|
|
70
72
|
result = discard_job(id)
|
71
73
|
if result[:success]
|
@@ -74,18 +76,18 @@ module SolidQueueMonitor
|
|
74
76
|
failed_count += 1
|
75
77
|
end
|
76
78
|
end
|
77
|
-
|
78
|
-
if success_count
|
79
|
-
{ success: true, message:
|
80
|
-
elsif success_count
|
79
|
+
|
80
|
+
if success_count.positive? && failed_count.zero?
|
81
|
+
{ success: true, message: 'All selected jobs have been discarded' }
|
82
|
+
elsif success_count.positive? && failed_count.positive?
|
81
83
|
{ success: true, message: "#{success_count} jobs discarded, #{failed_count} failed" }
|
82
84
|
else
|
83
|
-
{ success: false, message:
|
85
|
+
{ success: false, message: 'Failed to discard jobs' }
|
84
86
|
end
|
85
87
|
end
|
86
|
-
|
88
|
+
|
87
89
|
private
|
88
|
-
|
90
|
+
|
89
91
|
def get_queue_name(failed_execution, job)
|
90
92
|
if failed_execution.respond_to?(:queue_name) && failed_execution.queue_name.present?
|
91
93
|
failed_execution.queue_name
|
@@ -94,4 +96,4 @@ module SolidQueueMonitor
|
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|
97
|
-
end
|
99
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidQueueMonitor
|
2
4
|
class HtmlGenerator
|
3
5
|
include Rails.application.routes.url_helpers
|
@@ -50,9 +52,10 @@ module SolidQueueMonitor
|
|
50
52
|
</div>
|
51
53
|
HTML
|
52
54
|
end
|
53
|
-
|
55
|
+
|
54
56
|
def render_message
|
55
57
|
return '' unless @message
|
58
|
+
|
56
59
|
class_name = @message_type == 'success' ? 'message-success' : 'message-error'
|
57
60
|
<<-HTML
|
58
61
|
<div id="flash-message" class="message #{class_name}">#{@message}</div>
|
@@ -111,4 +114,4 @@ module SolidQueueMonitor
|
|
111
114
|
{ only_path: true }
|
112
115
|
end
|
113
116
|
end
|
114
|
-
end
|
117
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidQueueMonitor
|
2
4
|
class StatusCalculator
|
3
5
|
def initialize(job)
|
@@ -8,7 +10,8 @@ module SolidQueueMonitor
|
|
8
10
|
return 'completed' if @job.finished_at.present?
|
9
11
|
return 'failed' if @job.failed?
|
10
12
|
return 'scheduled' if @job.scheduled_at&.future?
|
13
|
+
|
11
14
|
'pending'
|
12
15
|
end
|
13
16
|
end
|
14
|
-
end
|
17
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidQueueMonitor
|
2
4
|
class StylesheetGenerator
|
3
5
|
def generate
|
@@ -127,7 +129,7 @@ module SolidQueueMonitor
|
|
127
129
|
white-space: nowrap;
|
128
130
|
}
|
129
131
|
|
130
|
-
.solid_queue_monitor th
|
132
|
+
.solid_queue_monitor th,#{' '}
|
131
133
|
.solid_queue_monitor td {
|
132
134
|
padding: 0.75rem 1rem;
|
133
135
|
text-align: left;
|
@@ -231,7 +233,7 @@ module SolidQueueMonitor
|
|
231
233
|
padding: 0.5rem 1rem;
|
232
234
|
font-size: 0.875rem;
|
233
235
|
}
|
234
|
-
|
236
|
+
#{' '}
|
235
237
|
.solid_queue_monitor .pagination-gap {
|
236
238
|
display: inline-flex;
|
237
239
|
align-items: center;
|
@@ -280,6 +282,51 @@ module SolidQueueMonitor
|
|
280
282
|
font-weight: 500;
|
281
283
|
}
|
282
284
|
|
285
|
+
/* Arguments styling */
|
286
|
+
.solid_queue_monitor .args-container {
|
287
|
+
position: relative;
|
288
|
+
max-height: 100px;
|
289
|
+
overflow: hidden;
|
290
|
+
}
|
291
|
+
|
292
|
+
.solid_queue_monitor .args-content {
|
293
|
+
display: block;
|
294
|
+
white-space: pre-wrap;
|
295
|
+
word-break: break-word;
|
296
|
+
max-height: 100px;
|
297
|
+
overflow-y: auto;
|
298
|
+
padding: 8px;
|
299
|
+
background: #f5f5f5;
|
300
|
+
border-radius: 4px;
|
301
|
+
font-size: 0.9em;
|
302
|
+
}
|
303
|
+
|
304
|
+
.solid_queue_monitor .args-single-line {
|
305
|
+
display: inline-block;
|
306
|
+
padding: 4px 8px;
|
307
|
+
background: #f5f5f5;
|
308
|
+
border-radius: 4px;
|
309
|
+
font-size: 0.9em;
|
310
|
+
}
|
311
|
+
|
312
|
+
.solid_queue_monitor .args-content::-webkit-scrollbar {
|
313
|
+
width: 8px;
|
314
|
+
}
|
315
|
+
|
316
|
+
.solid_queue_monitor .args-content::-webkit-scrollbar-track {
|
317
|
+
background: #f1f1f1;
|
318
|
+
border-radius: 4px;
|
319
|
+
}
|
320
|
+
|
321
|
+
.solid_queue_monitor .args-content::-webkit-scrollbar-thumb {
|
322
|
+
background: #888;
|
323
|
+
border-radius: 4px;
|
324
|
+
}
|
325
|
+
|
326
|
+
.solid_queue_monitor .args-content::-webkit-scrollbar-thumb:hover {
|
327
|
+
background: #666;
|
328
|
+
}
|
329
|
+
|
283
330
|
@media (max-width: 768px) {
|
284
331
|
.solid_queue_monitor .container {
|
285
332
|
padding: 0.5rem;
|
@@ -359,7 +406,7 @@ module SolidQueueMonitor
|
|
359
406
|
.solid_queue_monitor .filter-and-actions-container {
|
360
407
|
flex-direction: column;
|
361
408
|
}
|
362
|
-
|
409
|
+
#{' '}
|
363
410
|
.solid_queue_monitor .bulk-actions-container {
|
364
411
|
width: 100%;
|
365
412
|
}
|
@@ -429,8 +476,7 @@ module SolidQueueMonitor
|
|
429
476
|
.solid_queue_monitor .reset-button:hover {
|
430
477
|
background: #e5e7eb;
|
431
478
|
}
|
432
|
-
|
433
|
-
/* Action buttons for retry/discard */
|
479
|
+
|
434
480
|
.solid_queue_monitor .action-button {
|
435
481
|
padding: 0.5rem 1rem;
|
436
482
|
border-radius: 0.375rem;
|
@@ -441,50 +487,50 @@ module SolidQueueMonitor
|
|
441
487
|
border: none;
|
442
488
|
text-decoration: none;
|
443
489
|
}
|
444
|
-
|
490
|
+
|
445
491
|
.solid_queue_monitor .retry-button {
|
446
492
|
background: #3b82f6;
|
447
493
|
color: white;
|
448
494
|
}
|
449
|
-
|
495
|
+
|
450
496
|
.solid_queue_monitor .retry-button:hover {
|
451
497
|
background: #2563eb;
|
452
498
|
}
|
453
|
-
|
499
|
+
|
454
500
|
.solid_queue_monitor .discard-button {
|
455
501
|
background: #ef4444;
|
456
502
|
color: white;
|
457
503
|
}
|
458
|
-
|
504
|
+
|
459
505
|
.solid_queue_monitor .discard-button:hover {
|
460
506
|
background: #dc2626;
|
461
507
|
}
|
462
|
-
|
508
|
+
|
463
509
|
.solid_queue_monitor .action-button:disabled {
|
464
510
|
opacity: 0.5;
|
465
511
|
cursor: not-allowed;
|
466
512
|
}
|
467
|
-
|
513
|
+
|
468
514
|
.solid_queue_monitor .inline-form {
|
469
515
|
display: inline-block;
|
470
516
|
margin-right: 0.5rem;
|
471
517
|
}
|
472
|
-
|
518
|
+
|
473
519
|
.solid_queue_monitor .actions-cell {
|
474
520
|
white-space: nowrap;
|
475
521
|
}
|
476
|
-
|
522
|
+
|
477
523
|
.solid_queue_monitor .bulk-actions {
|
478
524
|
display: flex;
|
479
525
|
gap: 0.5rem;
|
480
526
|
}
|
481
|
-
|
527
|
+
|
482
528
|
.solid_queue_monitor .error-message {
|
483
529
|
color: #dc2626;
|
484
530
|
font-weight: 500;
|
485
531
|
margin-bottom: 0.25rem;
|
486
532
|
}
|
487
|
-
|
533
|
+
|
488
534
|
.solid_queue_monitor .error-backtrace {
|
489
535
|
font-size: 0.75rem;
|
490
536
|
white-space: pre-wrap;
|
@@ -495,21 +541,21 @@ module SolidQueueMonitor
|
|
495
541
|
border-radius: 0.25rem;
|
496
542
|
margin-top: 0.5rem;
|
497
543
|
}
|
498
|
-
|
544
|
+
|
499
545
|
.solid_queue_monitor details {
|
500
546
|
margin-top: 0.25rem;
|
501
547
|
}
|
502
|
-
|
548
|
+
|
503
549
|
.solid_queue_monitor summary {
|
504
550
|
cursor: pointer;
|
505
551
|
color: #6b7280;
|
506
552
|
font-size: 0.75rem;
|
507
553
|
}
|
508
|
-
|
554
|
+
|
509
555
|
.solid_queue_monitor summary:hover {
|
510
556
|
color: #4b5563;
|
511
557
|
}
|
512
|
-
|
558
|
+
|
513
559
|
.solid_queue_monitor .job-checkbox,
|
514
560
|
.solid_queue_monitor .select-all-checkbox {
|
515
561
|
width: 1rem;
|
@@ -525,7 +571,7 @@ module SolidQueueMonitor
|
|
525
571
|
border-radius: 0.5rem;
|
526
572
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
527
573
|
}
|
528
|
-
|
574
|
+
|
529
575
|
.solid_queue_monitor .bulk-actions-bar .action-button {
|
530
576
|
padding: 0.6rem 1rem;
|
531
577
|
font-size: 0.875rem;
|
@@ -535,11 +581,11 @@ module SolidQueueMonitor
|
|
535
581
|
background: var(--primary-color);
|
536
582
|
color: white;
|
537
583
|
}
|
538
|
-
|
584
|
+
|
539
585
|
.solid_queue_monitor .execute-button:hover {
|
540
586
|
background: #2563eb;
|
541
587
|
}
|
542
588
|
CSS
|
543
589
|
end
|
544
590
|
end
|
545
|
-
end
|
591
|
+
end
|
data/config/routes.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
SolidQueueMonitor::Engine.routes.draw do
|
2
4
|
root to: 'overview#index', as: :root
|
3
|
-
|
5
|
+
|
4
6
|
resources :ready_jobs, only: [:index]
|
5
7
|
resources :scheduled_jobs, only: [:index]
|
6
8
|
resources :recurring_jobs, only: [:index]
|
7
9
|
resources :failed_jobs, only: [:index]
|
8
10
|
resources :in_progress_jobs, only: [:index]
|
9
11
|
resources :queues, only: [:index]
|
10
|
-
|
12
|
+
|
11
13
|
post 'execute_jobs', to: 'scheduled_jobs#create', as: :execute_jobs
|
12
|
-
|
14
|
+
|
13
15
|
post 'retry_failed_job/:id', to: 'failed_jobs#retry', as: :retry_failed_job
|
14
16
|
post 'discard_failed_job/:id', to: 'failed_jobs#discard', as: :discard_failed_job
|
15
17
|
post 'retry_failed_jobs', to: 'failed_jobs#retry_all', as: :retry_failed_jobs
|
16
18
|
post 'discard_failed_jobs', to: 'failed_jobs#discard_all', as: :discard_failed_jobs
|
17
|
-
end
|
19
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails/generators/base'
|
2
4
|
|
3
5
|
module SolidQueueMonitor
|
@@ -6,18 +8,18 @@ module SolidQueueMonitor
|
|
6
8
|
source_root File.expand_path('templates', __dir__)
|
7
9
|
|
8
10
|
def copy_initializer
|
9
|
-
template
|
11
|
+
template 'initializer.rb', 'config/initializers/solid_queue_monitor.rb'
|
10
12
|
end
|
11
13
|
|
12
14
|
def add_routes
|
13
|
-
prepend_to_file
|
14
|
-
|
15
|
+
prepend_to_file 'config/routes.rb', "require 'solid_queue_monitor'\n\n"
|
16
|
+
|
15
17
|
route "mount SolidQueueMonitor::Engine => '/solid_queue'"
|
16
18
|
end
|
17
19
|
|
18
20
|
def show_readme
|
19
|
-
readme
|
21
|
+
readme 'README.md' if behavior == :invoke
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
23
|
-
end
|
25
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
SolidQueueMonitor.setup do |config|
|
2
4
|
# Enable or disable authentication
|
3
5
|
# When disabled, no authentication is required to access the monitor
|
@@ -11,4 +13,4 @@ SolidQueueMonitor.setup do |config|
|
|
11
13
|
|
12
14
|
# Number of jobs to display per page
|
13
15
|
# config.jobs_per_page = 25
|
14
|
-
end
|
16
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidQueueMonitor
|
2
4
|
class Engine < ::Rails::Engine
|
3
5
|
isolate_namespace SolidQueueMonitor
|
4
6
|
|
5
7
|
config.autoload_paths << root.join('app', 'services')
|
6
|
-
|
8
|
+
|
7
9
|
# Optional: Add eager loading for production
|
8
10
|
config.eager_load_paths << root.join('app', 'services')
|
9
11
|
|
10
|
-
initializer
|
12
|
+
initializer 'solid_queue_monitor.assets' do |app|
|
11
13
|
# Optional: Add assets if needed
|
12
14
|
end
|
13
15
|
end
|
14
|
-
end
|
16
|
+
end
|
data/lib/solid_queue_monitor.rb
CHANGED
@@ -1,22 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
3
|
+
require_relative 'solid_queue_monitor/version'
|
4
|
+
require_relative 'solid_queue_monitor/engine'
|
5
5
|
|
6
6
|
module SolidQueueMonitor
|
7
7
|
class Error < StandardError; end
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
mattr_accessor :password
|
13
|
-
@@password = 'password'
|
14
|
-
|
15
|
-
mattr_accessor :jobs_per_page
|
16
|
-
@@jobs_per_page = 25
|
8
|
+
class << self
|
9
|
+
attr_accessor :username, :password, :jobs_per_page, :authentication_enabled
|
10
|
+
end
|
17
11
|
|
18
|
-
|
19
|
-
|
12
|
+
@username = 'admin'
|
13
|
+
@password = 'password'
|
14
|
+
@jobs_per_page = 25
|
15
|
+
@authentication_enabled = false
|
20
16
|
|
21
17
|
def self.setup
|
22
18
|
yield self
|