solid_queue_monitor 0.2.0 → 0.3.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -10
  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 +42 -41
  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 +23 -21
  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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 264dd6a6542855e5209702c11fbb46c1c267b5c8d48d530887030f924bdb929f
4
- data.tar.gz: 4d5a33c4152f29d0c3ba4c9fd6c59582e7af9694e85469a78cde9a9d173a4433
3
+ metadata.gz: d2911139409c2a387a2c425c0ef9927071a05dcf5f718e5aefc7bfb86cc4b7b6
4
+ data.tar.gz: 398de34669f64b9d4cab2cf1ed7e1f19da6fcd56b67df8da2c2682410308a905
5
5
  SHA512:
6
- metadata.gz: 704927588ba7329d988a7533ab70e6b444254abc64a15684fbeccce47221c929c39701abd8fbb02dbebf444c0c3a9521cbcc84260d06d3c6fdafca6e01ad2be5
7
- data.tar.gz: 8b0a608d0ae89c54719dd5286e9de77cb4145d1f1c3dc7c3f8c1b46a521ae1b2e0ad37d35e7c2796a187122fc38f401b423a46109cc81328cff6805274338357
6
+ metadata.gz: 9357fee483f20555b92b1fd913224c536ae934bb8442968f42470c672c1cc19a8388d13a5cd7741f36158a67c594913074b5cdafbeae8caaa6aa67e5161cc373
7
+ data.tar.gz: 32a1c6d65dbbcf9d837ded2fca261d0d715546c446a716073881c7a199d7ee3d561a94971880f5c144f270484199e265fd0b367230babd811891409b56849a2e
data/README.md CHANGED
@@ -15,13 +15,16 @@ A lightweight, zero-dependency web interface for monitoring Solid Queue backgrou
15
15
 
16
16
  ## Features
17
17
 
18
- - **Dashboard Overview**: Get a quick snapshot of your job queue with statistics and counts
19
- - **Job Filtering**: Filter jobs by class name, queue name, and status
20
- - **Job Management**: Execute scheduled jobs on demand
21
- - **Failed Job Inspection**: View detailed error information for failed jobs
22
- - **Queue Monitoring**: Track job distribution across different queues
23
- - **Recurring Jobs**: Monitor and manage recurring background tasks
24
- - **Pagination**: Navigate through large job lists with ease
18
+ - **Dashboard Overview**: Get a quick snapshot of your queue's health with statistics on all job types
19
+ - **Ready Jobs**: View jobs that are ready to be executed
20
+ - **In Progress Jobs**: Monitor jobs currently being processed by workers
21
+ - **Scheduled Jobs**: See upcoming jobs scheduled for future execution
22
+ - **Recurring Jobs**: Manage periodic jobs that run on a schedule
23
+ - **Failed Jobs**: Track and debug failed jobs, with the ability to retry or discard them
24
+ - **Queue Management**: View and filter jobs by queue
25
+ - **Advanced Job Filtering**: Filter jobs by class name, queue, status, and job arguments
26
+ - **Quick Actions**: Retry or discard failed jobs directly from any view
27
+ - **Performance Optimized**: Designed for high-volume applications with smart pagination
25
28
  - **Optional Authentication**: Secure your dashboard with HTTP Basic Authentication
26
29
  - **Responsive Design**: Works on desktop and mobile devices
27
30
  - **Zero Dependencies**: No additional JavaScript libraries or frameworks required
@@ -30,7 +33,7 @@ A lightweight, zero-dependency web interface for monitoring Solid Queue backgrou
30
33
 
31
34
  ### Dashboard Overview
32
35
 
33
- ![Dashboard Overview](screenshots/dashboard.png)
36
+ ![Dashboard Overview](screenshots/dashboard-2.png)
34
37
 
35
38
  ### Failed Jobs
36
39
 
@@ -41,7 +44,7 @@ A lightweight, zero-dependency web interface for monitoring Solid Queue backgrou
41
44
  Add this line to your application's Gemfile:
42
45
 
43
46
  ```ruby
44
- gem 'solid_queue_monitor', '~> 0.2.0'
47
+ gem 'solid_queue_monitor', '~> 0.3.0'
45
48
  ```
46
49
 
47
50
  Then execute:
@@ -109,6 +112,17 @@ The dashboard provides several views:
109
112
 
110
113
  For API-only Rails applications, SolidQueueMonitor works out of the box without requiring you to enable the asset pipeline or webpacker. This makes it an ideal choice for monitoring background jobs in modern API-based architectures.
111
114
 
115
+ ### Job Filtering
116
+
117
+ You can filter jobs by:
118
+
119
+ - **Class Name**: Filter by job class name
120
+ - **Queue Name**: Filter by queue name
121
+ - **Job Arguments**: Search within job arguments using case-insensitive partial matching
122
+ - **Status**: Filter by job status (completed, failed, scheduled, pending)
123
+
124
+ This makes it easy to find specific jobs when debugging issues in your application.
125
+
112
126
  ## Use Cases
113
127
 
114
128
  - **Production Monitoring**: Keep an eye on your background job processing in production environments
@@ -151,4 +165,4 @@ Everyone interacting in the SolidQueueMonitor project's codebases, issue tracker
151
165
 
152
166
  - [Solid Queue](https://github.com/rails/solid_queue) - The official Rails background job framework
153
167
  - [Rails](https://github.com/rails/rails) - The web application framework
154
- - [ActiveJob](https://github.com/rails/rails/tree/main/activejob) - Rails job frameworkk
168
+ - [ActiveJob](https://github.com/rails/rails/tree/main/activejob) - Rails job framework
data/Rakefile CHANGED
@@ -1,23 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  task default: :spec
9
9
 
10
10
  namespace :db do
11
- task :setup do
11
+ task setup: :environment do
12
12
  require 'fileutils'
13
13
  FileUtils.mkdir_p 'spec/dummy/db'
14
- system("cd spec/dummy && bundle exec rails db:environment:set RAILS_ENV=test")
15
- system("cd spec/dummy && bundle exec rails db:schema:load RAILS_ENV=test")
14
+ system('cd spec/dummy && bundle exec rails db:environment:set RAILS_ENV=test')
15
+ system('cd spec/dummy && bundle exec rails db:schema:load RAILS_ENV=test')
16
16
  end
17
17
  end
18
18
 
19
- task :prepare_test_env do
20
- Rake::Task["db:setup"].invoke
19
+ task prepare_test_env: :environment do
20
+ Rake::Task['db:setup'].invoke
21
21
  end
22
22
 
23
- task :spec => :prepare_test_env
23
+ task spec: :prepare_test_env
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidQueueMonitor
4
+ class ApplicationController < ActionController::Base
5
+ include ActionController::HttpAuthentication::Basic::ControllerMethods
6
+ include ActionController::Flash
7
+
8
+ before_action :authenticate, if: -> { SolidQueueMonitor::AuthenticationService.authentication_required? }
9
+ layout false
10
+ skip_before_action :verify_authenticity_token
11
+
12
+ def set_flash_message(message, type)
13
+ session[:flash_message] = message
14
+ session[:flash_type] = type
15
+ end
16
+
17
+ private
18
+
19
+ def authenticate
20
+ authenticate_or_request_with_http_basic do |username, password|
21
+ SolidQueueMonitor::AuthenticationService.authenticate(username, password)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,26 +1,7 @@
1
- module SolidQueueMonitor
2
- class BaseController < ActionController::Base
3
- include ActionController::HttpAuthentication::Basic::ControllerMethods
4
- include ActionController::Flash
5
-
6
- before_action :authenticate, if: -> { SolidQueueMonitor::AuthenticationService.authentication_required? }
7
- layout false
8
- skip_before_action :verify_authenticity_token
9
-
10
- # Define a helper method for setting flash messages
11
- def set_flash_message(message, type)
12
- session[:flash_message] = message
13
- session[:flash_type] = type
14
- end
15
-
16
- private
17
-
18
- def authenticate
19
- authenticate_or_request_with_http_basic do |username, password|
20
- SolidQueueMonitor::AuthenticationService.authenticate(username, password)
21
- end
22
- end
1
+ # frozen_string_literal: true
23
2
 
3
+ module SolidQueueMonitor
4
+ class BaseController < SolidQueueMonitor::ApplicationController
24
5
  def paginate(relation)
25
6
  PaginationService.new(relation, current_page, per_page).paginate
26
7
  end
@@ -29,18 +10,18 @@ module SolidQueueMonitor
29
10
  # Get flash message from session
30
11
  message = session[:flash_message]
31
12
  message_type = session[:flash_type]
32
-
13
+
33
14
  # Clear the flash message from session after using it
34
15
  session.delete(:flash_message)
35
16
  session.delete(:flash_type)
36
-
17
+
37
18
  html = SolidQueueMonitor::HtmlGenerator.new(
38
19
  title: title,
39
20
  content: content,
40
21
  message: message,
41
22
  message_type: message_type
42
23
  ).generate
43
-
24
+
44
25
  render html: html.html_safe
45
26
  end
46
27
 
@@ -55,22 +36,22 @@ module SolidQueueMonitor
55
36
  # Preload job statuses to avoid N+1 queries
56
37
  def preload_job_statuses(jobs)
57
38
  return if jobs.empty?
58
-
39
+
59
40
  # Get all job IDs
60
41
  job_ids = jobs.map(&:id)
61
-
42
+
62
43
  # Find all failed jobs in a single query
63
44
  failed_job_ids = SolidQueue::FailedExecution.where(job_id: job_ids).pluck(:job_id)
64
-
45
+
65
46
  # Find all scheduled jobs in a single query
66
47
  scheduled_job_ids = SolidQueue::ScheduledExecution.where(job_id: job_ids).pluck(:job_id)
67
-
48
+
68
49
  # Attach the status information to each job
69
50
  jobs.each do |job|
70
51
  job.instance_variable_set(:@failed, failed_job_ids.include?(job.id))
71
52
  job.instance_variable_set(:@scheduled, scheduled_job_ids.include?(job.id))
72
53
  end
73
-
54
+
74
55
  # Define the method to check if a job is failed
75
56
  SolidQueue::Job.class_eval do
76
57
  def failed?
@@ -80,7 +61,7 @@ module SolidQueueMonitor
80
61
  SolidQueue::FailedExecution.exists?(job_id: id)
81
62
  end
82
63
  end
83
-
64
+
84
65
  def scheduled?
85
66
  if instance_variable_defined?(:@scheduled)
86
67
  @scheduled
@@ -92,9 +73,10 @@ module SolidQueueMonitor
92
73
  end
93
74
 
94
75
  def filter_jobs(relation)
95
- relation = relation.where("class_name LIKE ?", "%#{params[:class_name]}%") if params[:class_name].present?
96
- relation = relation.where("queue_name LIKE ?", "%#{params[:queue_name]}%") if params[:queue_name].present?
97
-
76
+ relation = relation.where('class_name LIKE ?', "%#{params[:class_name]}%") if params[:class_name].present?
77
+ relation = relation.where('queue_name LIKE ?', "%#{params[:queue_name]}%") if params[:queue_name].present?
78
+ relation = filter_by_arguments(relation) if params[:arguments].present?
79
+
98
80
  if params[:status].present?
99
81
  case params[:status]
100
82
  when 'completed'
@@ -110,76 +92,96 @@ module SolidQueueMonitor
110
92
  failed_job_ids = SolidQueue::FailedExecution.pluck(:job_id)
111
93
  scheduled_job_ids = SolidQueue::ScheduledExecution.pluck(:job_id)
112
94
  relation = relation.where(finished_at: nil)
113
- .where.not(id: failed_job_ids + scheduled_job_ids)
95
+ .where.not(id: failed_job_ids + scheduled_job_ids)
114
96
  end
115
97
  end
116
-
98
+
117
99
  relation
118
100
  end
119
101
 
102
+ def filter_by_arguments(relation)
103
+ # Use ILIKE for case-insensitive search in PostgreSQL
104
+ relation.where('arguments::text ILIKE ?', "%#{params[:arguments]}%")
105
+ end
106
+
120
107
  def filter_ready_jobs(relation)
121
- return relation unless params[:class_name].present? || params[:queue_name].present?
122
-
108
+ return relation unless params[:class_name].present? || params[:queue_name].present? || params[:arguments].present?
109
+
123
110
  if params[:class_name].present?
124
- job_ids = SolidQueue::Job.where("class_name LIKE ?", "%#{params[:class_name]}%").pluck(:id)
111
+ job_ids = SolidQueue::Job.where('class_name LIKE ?', "%#{params[:class_name]}%").pluck(:id)
125
112
  relation = relation.where(job_id: job_ids)
126
113
  end
127
-
128
- if params[:queue_name].present?
129
- relation = relation.where("queue_name LIKE ?", "%#{params[:queue_name]}%")
114
+
115
+ relation = relation.where('queue_name LIKE ?', "%#{params[:queue_name]}%") if params[:queue_name].present?
116
+
117
+ # Add arguments filtering
118
+ if params[:arguments].present?
119
+ job_ids = SolidQueue::Job.where('arguments::text ILIKE ?', "%#{params[:arguments]}%").pluck(:id)
120
+ relation = relation.where(job_id: job_ids)
130
121
  end
131
-
122
+
132
123
  relation
133
124
  end
134
125
 
135
126
  def filter_scheduled_jobs(relation)
136
- return relation unless params[:class_name].present? || params[:queue_name].present?
137
-
127
+ return relation unless params[:class_name].present? || params[:queue_name].present? || params[:arguments].present?
128
+
138
129
  if params[:class_name].present?
139
- job_ids = SolidQueue::Job.where("class_name LIKE ?", "%#{params[:class_name]}%").pluck(:id)
130
+ job_ids = SolidQueue::Job.where('class_name LIKE ?', "%#{params[:class_name]}%").pluck(:id)
140
131
  relation = relation.where(job_id: job_ids)
141
132
  end
142
-
143
- if params[:queue_name].present?
144
- relation = relation.where("queue_name LIKE ?", "%#{params[:queue_name]}%")
133
+
134
+ relation = relation.where('queue_name LIKE ?', "%#{params[:queue_name]}%") if params[:queue_name].present?
135
+
136
+ # Add arguments filtering
137
+ if params[:arguments].present?
138
+ job_ids = SolidQueue::Job.where('arguments::text ILIKE ?', "%#{params[:arguments]}%").pluck(:id)
139
+ relation = relation.where(job_id: job_ids)
145
140
  end
146
-
141
+
147
142
  relation
148
143
  end
149
144
 
150
145
  def filter_recurring_jobs(relation)
151
- return relation unless params[:class_name].present? || params[:queue_name].present?
152
-
153
- if params[:class_name].present?
154
- relation = relation.where("class_name LIKE ?", "%#{params[:class_name]}%")
155
- end
156
-
157
- if params[:queue_name].present?
158
- relation = relation.where("queue_name LIKE ?", "%#{params[:queue_name]}%")
146
+ return relation unless params[:class_name].present? || params[:queue_name].present? || params[:arguments].present?
147
+
148
+ relation = relation.where('class_name LIKE ?', "%#{params[:class_name]}%") if params[:class_name].present?
149
+ relation = relation.where('queue_name LIKE ?', "%#{params[:queue_name]}%") if params[:queue_name].present?
150
+
151
+ # Add arguments filtering if the model has arguments column
152
+ if params[:arguments].present? && relation.column_names.include?('arguments')
153
+ relation = relation.where('arguments::text ILIKE ?',
154
+ "%#{params[:arguments]}%")
159
155
  end
160
-
156
+
161
157
  relation
162
158
  end
163
159
 
164
160
  def filter_failed_jobs(relation)
165
- return relation unless params[:class_name].present? || params[:queue_name].present?
166
-
161
+ return relation unless params[:class_name].present? || params[:queue_name].present? || params[:arguments].present?
162
+
167
163
  if params[:class_name].present?
168
- job_ids = SolidQueue::Job.where("class_name LIKE ?", "%#{params[:class_name]}%").pluck(:id)
164
+ job_ids = SolidQueue::Job.where('class_name LIKE ?', "%#{params[:class_name]}%").pluck(:id)
169
165
  relation = relation.where(job_id: job_ids)
170
166
  end
171
-
167
+
172
168
  if params[:queue_name].present?
173
169
  # Check if FailedExecution has queue_name column
174
170
  if relation.column_names.include?('queue_name')
175
- relation = relation.where("queue_name LIKE ?", "%#{params[:queue_name]}%")
171
+ relation = relation.where('queue_name LIKE ?', "%#{params[:queue_name]}%")
176
172
  else
177
173
  # If not, filter by job's queue_name
178
- job_ids = SolidQueue::Job.where("queue_name LIKE ?", "%#{params[:queue_name]}%").pluck(:id)
174
+ job_ids = SolidQueue::Job.where('queue_name LIKE ?', "%#{params[:queue_name]}%").pluck(:id)
179
175
  relation = relation.where(job_id: job_ids)
180
176
  end
181
177
  end
182
-
178
+
179
+ # Add arguments filtering
180
+ if params[:arguments].present?
181
+ job_ids = SolidQueue::Job.where('arguments::text ILIKE ?', "%#{params[:arguments]}%").pluck(:id)
182
+ relation = relation.where(job_id: job_ids)
183
+ end
184
+
183
185
  relation
184
186
  end
185
187
 
@@ -187,8 +189,9 @@ module SolidQueueMonitor
187
189
  {
188
190
  class_name: params[:class_name],
189
191
  queue_name: params[:queue_name],
192
+ arguments: params[:arguments],
190
193
  status: params[:status]
191
194
  }
192
195
  end
193
196
  end
194
- end
197
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class FailedJobsController < BaseController
3
5
  def index
@@ -5,10 +7,9 @@ module SolidQueueMonitor
5
7
  @failed_jobs = paginate(filter_failed_jobs(base_query))
6
8
 
7
9
  render_page('Failed Jobs', SolidQueueMonitor::FailedJobsPresenter.new(@failed_jobs[:records],
8
- current_page: @failed_jobs[:current_page],
9
- total_pages: @failed_jobs[:total_pages],
10
- filters: filter_params
11
- ).render)
10
+ current_page: @failed_jobs[:current_page],
11
+ total_pages: @failed_jobs[:total_pages],
12
+ filters: filter_params).render)
12
13
  end
13
14
 
14
15
  def retry
@@ -21,7 +22,7 @@ module SolidQueueMonitor
21
22
  set_flash_message("Failed to retry job #{id}.", 'error')
22
23
  end
23
24
 
24
- redirect_to params[:redirect_to].present? ? params[:redirect_to] : failed_jobs_path
25
+ redirect_to(params[:redirect_to].presence || failed_jobs_path)
25
26
  end
26
27
 
27
28
  def discard
@@ -34,7 +35,7 @@ module SolidQueueMonitor
34
35
  set_flash_message("Failed to discard job #{id}.", 'error')
35
36
  end
36
37
 
37
- redirect_to params[:redirect_to].present? ? params[:redirect_to] : failed_jobs_path
38
+ redirect_to(params[:redirect_to].presence || failed_jobs_path)
38
39
  end
39
40
 
40
41
  def retry_all
@@ -59,4 +60,4 @@ module SolidQueueMonitor
59
60
  redirect_to failed_jobs_path
60
61
  end
61
62
  end
62
- end
63
+ end
@@ -1,27 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class InProgressJobsController < BaseController
3
5
  def index
4
6
  base_query = SolidQueue::ClaimedExecution.includes(:job).order(created_at: :desc)
5
7
  @in_progress_jobs = paginate(filter_in_progress_jobs(base_query))
6
-
8
+
7
9
  render_page('In Progress Jobs', SolidQueueMonitor::InProgressJobsPresenter.new(@in_progress_jobs[:records],
8
- current_page: @in_progress_jobs[:current_page],
9
- total_pages: @in_progress_jobs[:total_pages],
10
- filters: filter_params
11
- ).render)
10
+ current_page: @in_progress_jobs[:current_page],
11
+ total_pages: @in_progress_jobs[:total_pages],
12
+ filters: filter_params).render)
12
13
  end
13
14
 
14
15
  private
15
16
 
16
17
  def filter_in_progress_jobs(relation)
17
- return relation unless params[:class_name].present?
18
-
18
+ return relation if params[:class_name].blank? && params[:arguments].blank?
19
+
19
20
  if params[:class_name].present?
20
- job_ids = SolidQueue::Job.where("class_name LIKE ?", "%#{params[:class_name]}%").pluck(:id)
21
+ job_ids = SolidQueue::Job.where('class_name LIKE ?', "%#{params[:class_name]}%").pluck(:id)
21
22
  relation = relation.where(job_id: job_ids)
22
23
  end
23
-
24
+
25
+ if params[:arguments].present?
26
+ job_ids = SolidQueue::Job.where('arguments::text ILIKE ?', "%#{params[:arguments]}%").pluck(:id)
27
+ relation = relation.where(job_id: job_ids)
28
+ end
29
+
24
30
  relation
25
31
  end
26
32
  end
27
- end
33
+ end
@@ -1,25 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class OverviewController < BaseController
3
5
  def index
4
6
  @stats = SolidQueueMonitor::StatsCalculator.calculate
5
-
7
+
6
8
  recent_jobs_query = SolidQueue::Job.order(created_at: :desc).limit(100)
7
9
  @recent_jobs = paginate(filter_jobs(recent_jobs_query))
8
-
10
+
9
11
  preload_job_statuses(@recent_jobs[:records])
10
-
12
+
11
13
  render_page('Overview', generate_overview_content)
12
14
  end
13
-
15
+
14
16
  private
15
-
17
+
16
18
  def generate_overview_content
17
- SolidQueueMonitor::StatsPresenter.new(@stats).render +
18
- SolidQueueMonitor::JobsPresenter.new(@recent_jobs[:records],
19
- current_page: @recent_jobs[:current_page],
20
- total_pages: @recent_jobs[:total_pages],
21
- filters: filter_params
22
- ).render
19
+ SolidQueueMonitor::StatsPresenter.new(@stats).render +
20
+ SolidQueueMonitor::JobsPresenter.new(@recent_jobs[:records],
21
+ current_page: @recent_jobs[:current_page],
22
+ total_pages: @recent_jobs[:total_pages],
23
+ filters: filter_params).render
23
24
  end
24
25
  end
25
- end
26
+ end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class QueuesController < BaseController
3
5
  def index
4
6
  @queues = SolidQueue::Job.group(:queue_name)
5
7
  .select('queue_name, COUNT(*) as job_count')
6
8
  .order('job_count DESC')
7
-
9
+
8
10
  render_page('Queues', SolidQueueMonitor::QueuesPresenter.new(@queues).render)
9
11
  end
10
12
  end
11
- end
13
+ end
@@ -1,14 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class ReadyJobsController < BaseController
3
5
  def index
4
6
  base_query = SolidQueue::ReadyExecution.includes(:job).order(created_at: :desc)
5
7
  @ready_jobs = paginate(filter_ready_jobs(base_query))
6
-
7
- render_page('Ready Jobs', SolidQueueMonitor::ReadyJobsPresenter.new(@ready_jobs[:records],
8
- current_page: @ready_jobs[:current_page],
9
- total_pages: @ready_jobs[:total_pages],
10
- filters: filter_params
11
- ).render)
8
+
9
+ render_page('Ready Jobs', SolidQueueMonitor::ReadyJobsPresenter.new(@ready_jobs[:records],
10
+ current_page: @ready_jobs[:current_page],
11
+ total_pages: @ready_jobs[:total_pages],
12
+ filters: filter_params).render)
12
13
  end
13
14
  end
14
- end
15
+ end
@@ -1,14 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class RecurringJobsController < BaseController
3
5
  def index
4
6
  base_query = filter_recurring_jobs(SolidQueue::RecurringTask.order(:key))
5
7
  @recurring_jobs = paginate(base_query)
6
-
8
+
7
9
  render_page('Recurring Jobs', SolidQueueMonitor::RecurringJobsPresenter.new(@recurring_jobs[:records],
8
- current_page: @recurring_jobs[:current_page],
9
- total_pages: @recurring_jobs[:total_pages],
10
- filters: filter_params
11
- ).render)
10
+ current_page: @recurring_jobs[:current_page],
11
+ total_pages: @recurring_jobs[:total_pages],
12
+ filters: filter_params).render)
12
13
  end
13
14
  end
14
- end
15
+ end
@@ -1,16 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolidQueueMonitor
2
4
  class ScheduledJobsController < BaseController
3
5
  def index
4
6
  base_query = SolidQueue::ScheduledExecution.includes(:job).order(scheduled_at: :asc)
5
7
  @scheduled_jobs = paginate(filter_scheduled_jobs(base_query))
6
-
8
+
7
9
  render_page('Scheduled Jobs', SolidQueueMonitor::ScheduledJobsPresenter.new(@scheduled_jobs[:records],
8
- current_page: @scheduled_jobs[:current_page],
9
- total_pages: @scheduled_jobs[:total_pages],
10
- filters: filter_params
11
- ).render)
10
+ current_page: @scheduled_jobs[:current_page],
11
+ total_pages: @scheduled_jobs[:total_pages],
12
+ filters: filter_params).render)
12
13
  end
13
-
14
+
14
15
  def create
15
16
  if params[:job_ids].present?
16
17
  SolidQueueMonitor::ExecuteJobService.new.execute_many(params[:job_ids])
@@ -21,4 +22,4 @@ module SolidQueueMonitor
21
22
  redirect_to scheduled_jobs_path
22
23
  end
23
24
  end
24
- end
25
+ end