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.
- checksums.yaml +4 -4
- data/README.md +24 -10
- 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 +42 -41
- 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 +23 -21
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2911139409c2a387a2c425c0ef9927071a05dcf5f718e5aefc7bfb86cc4b7b6
|
4
|
+
data.tar.gz: 398de34669f64b9d4cab2cf1ed7e1f19da6fcd56b67df8da2c2682410308a905
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
19
|
-
- **
|
20
|
-
- **
|
21
|
-
- **
|
22
|
-
- **
|
23
|
-
- **
|
24
|
-
- **
|
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
|
-

|
36
|
+

|
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.
|
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
|
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
|
4
|
-
require
|
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 :
|
11
|
+
task setup: :environment do
|
12
12
|
require 'fileutils'
|
13
13
|
FileUtils.mkdir_p 'spec/dummy/db'
|
14
|
-
system(
|
15
|
-
system(
|
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 :
|
20
|
-
Rake::Task[
|
19
|
+
task prepare_test_env: :environment do
|
20
|
+
Rake::Task['db:setup'].invoke
|
21
21
|
end
|
22
22
|
|
23
|
-
task :
|
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
|
-
|
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(
|
96
|
-
relation = relation.where(
|
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
|
-
|
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(
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
157
|
-
if params[:
|
158
|
-
relation = relation.where(
|
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(
|
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(
|
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(
|
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
|
-
|
9
|
-
|
10
|
-
|
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
|
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
|
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
|
-
|
9
|
-
|
10
|
-
|
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
|
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(
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
9
|
-
|
10
|
-
|
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
|