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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -11
  3. data/Rakefile +8 -8
  4. data/app/controllers/solid_queue_monitor/application_controller.rb +25 -0
  5. data/app/controllers/solid_queue_monitor/base_controller.rb +70 -67
  6. data/app/controllers/solid_queue_monitor/failed_jobs_controller.rb +8 -7
  7. data/app/controllers/solid_queue_monitor/in_progress_jobs_controller.rb +16 -10
  8. data/app/controllers/solid_queue_monitor/overview_controller.rb +13 -12
  9. data/app/controllers/solid_queue_monitor/queues_controller.rb +4 -2
  10. data/app/controllers/solid_queue_monitor/ready_jobs_controller.rb +8 -7
  11. data/app/controllers/solid_queue_monitor/recurring_jobs_controller.rb +7 -6
  12. data/app/controllers/solid_queue_monitor/scheduled_jobs_controller.rb +8 -7
  13. data/app/presenters/solid_queue_monitor/base_presenter.rb +70 -53
  14. data/app/presenters/solid_queue_monitor/failed_jobs_presenter.rb +51 -41
  15. data/app/presenters/solid_queue_monitor/in_progress_jobs_presenter.rb +13 -2
  16. data/app/presenters/solid_queue_monitor/jobs_presenter.rb +18 -9
  17. data/app/presenters/solid_queue_monitor/queues_presenter.rb +5 -5
  18. data/app/presenters/solid_queue_monitor/ready_jobs_presenter.rb +10 -2
  19. data/app/presenters/solid_queue_monitor/recurring_jobs_presenter.rb +5 -2
  20. data/app/presenters/solid_queue_monitor/scheduled_jobs_presenter.rb +15 -9
  21. data/app/presenters/solid_queue_monitor/stats_presenter.rb +3 -1
  22. data/app/services/solid_queue_monitor/authentication_service.rb +7 -5
  23. data/app/services/solid_queue_monitor/execute_job_service.rb +3 -1
  24. data/app/services/solid_queue_monitor/failed_job_service.rb +38 -36
  25. data/app/services/solid_queue_monitor/html_generator.rb +5 -2
  26. data/app/services/solid_queue_monitor/pagination_service.rb +3 -1
  27. data/app/services/solid_queue_monitor/stats_calculator.rb +3 -1
  28. data/app/services/solid_queue_monitor/status_calculator.rb +4 -1
  29. data/app/services/solid_queue_monitor/stylesheet_generator.rb +68 -22
  30. data/config/initializers/solid_queue_monitor.rb +3 -1
  31. data/config/routes.rb +6 -4
  32. data/lib/generators/solid_queue_monitor/install_generator.rb +7 -5
  33. data/lib/generators/solid_queue_monitor/templates/initializer.rb +3 -1
  34. data/lib/solid_queue_monitor/engine.rb +5 -3
  35. data/lib/solid_queue_monitor/version.rb +2 -2
  36. data/lib/solid_queue_monitor.rb +9 -13
  37. data/lib/tasks/app.rake +42 -40
  38. metadata +9 -148
  39. 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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class StatsPresenter < BasePresenter
3
5
  def initialize(stats)
@@ -32,4 +34,4 @@ module SolidQueueMonitor
32
34
  HTML
33
35
  end
34
36
  end
35
- end
37
+ 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
- password == SolidQueueMonitor.password
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class ExecuteJobService
3
5
  def call(id)
@@ -25,4 +27,4 @@ module SolidQueueMonitor
25
27
  end
26
28
  end
27
29
  end
28
- end
30
+ 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: "Failed job not found" } unless failed_execution
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: "Associated job not found" } unless job
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: "Job moved to ready queue for retry" }
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: "Failed job not found" } unless failed_execution
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: "Associated job not found" } unless job
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: "Job has been discarded" }
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: "No jobs selected" } if job_ids.blank?
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 > 0 && failed_count == 0
55
- { success: true, message: "All selected jobs have been queued for retry" }
56
- elsif success_count > 0 && failed_count > 0
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: "Failed to retry jobs" }
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: "No jobs selected" } if job_ids.blank?
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 > 0 && failed_count == 0
79
- { success: true, message: "All selected jobs have been discarded" }
80
- elsif success_count > 0 && failed_count > 0
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: "Failed to discard jobs" }
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 PaginationService
3
5
  def initialize(relation, page, per_page)
@@ -28,4 +30,4 @@ module SolidQueueMonitor
28
30
  @relation.limit(@per_page).offset(offset)
29
31
  end
30
32
  end
31
- end
33
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class StatsCalculator
3
5
  def self.calculate
@@ -13,4 +15,4 @@ module SolidQueueMonitor
13
15
  }
14
16
  end
15
17
  end
16
- end
18
+ 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
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  SolidQueueMonitor.setup do |config|
2
4
  config.username = 'admin' # Change this in your application
3
5
  config.password = 'password' # Change this in your application
4
6
  config.jobs_per_page = 25
5
- end
7
+ 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 "initializer.rb", "config/initializers/solid_queue_monitor.rb"
11
+ template 'initializer.rb', 'config/initializers/solid_queue_monitor.rb'
10
12
  end
11
13
 
12
14
  def add_routes
13
- prepend_to_file "config/routes.rb", "require 'solid_queue_monitor'\n\n"
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 "README.md" if behavior == :invoke
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 "solid_queue_monitor.assets" do |app|
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidQueueMonitor
4
- VERSION = "0.2.0"
5
- end
4
+ VERSION = '0.3.1'
5
+ end
@@ -1,22 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "solid_queue_monitor/version"
4
- require_relative "solid_queue_monitor/engine"
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
- # Configuration options
9
- mattr_accessor :username
10
- @@username = 'admin'
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
- mattr_accessor :authentication_enabled
19
- @@authentication_enabled = false
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