solid_queue_web 0.3.0 → 0.4.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/app/assets/stylesheets/solid_queue_web/application.css +12 -0
- data/app/controllers/solid_queue_web/jobs_controller.rb +39 -28
- data/app/views/solid_queue_web/dashboard/index.html.erb +14 -14
- data/app/views/solid_queue_web/jobs/destroy.turbo_stream.erb +9 -0
- data/app/views/solid_queue_web/jobs/index.html.erb +13 -11
- data/lib/solid_queue_web/engine.rb +1 -0
- data/lib/solid_queue_web/version.rb +1 -1
- metadata +16 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 439fb2adc133452cb89ebcf1d4376e9fd45d4e19a7f1ebc4a37d4b72e89f4b54
|
|
4
|
+
data.tar.gz: 644a02acffccaeba6420d1374f411796e4219b4883d6cdaa17ffe25b1c2a4b01
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b65ef968cbcd72f56df7039b7cfa22fbbc94db21d7e1edeabdad1a07293ba35f17b614471d1034fdcf0d2979ed8bfb3deacb2101b99667f87f1553546b6ad36c
|
|
7
|
+
data.tar.gz: 616474ab808602a116c997787580e0d665c6e4ba1dab9b36eab60d74b36285bd629198666fcbd4e16a0128a63875f079a43571470ff3a0320e9316b9a8c8d599
|
|
@@ -139,6 +139,18 @@ body {
|
|
|
139
139
|
.sqd-stat--queues .sqd-stat__value { color: var(--purple); }
|
|
140
140
|
.sqd-stat--processes .sqd-stat__value { color: var(--muted); }
|
|
141
141
|
|
|
142
|
+
.sqd-stat--link {
|
|
143
|
+
display: block;
|
|
144
|
+
text-decoration: none;
|
|
145
|
+
color: inherit;
|
|
146
|
+
transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
|
|
147
|
+
}
|
|
148
|
+
.sqd-stat--link:hover {
|
|
149
|
+
border-color: var(--primary);
|
|
150
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
151
|
+
transform: translateY(-2px);
|
|
152
|
+
}
|
|
153
|
+
|
|
142
154
|
/* Tables */
|
|
143
155
|
.sqd-card {
|
|
144
156
|
background: var(--surface);
|
|
@@ -3,19 +3,21 @@ module SolidQueueWeb
|
|
|
3
3
|
STATUSES = %w[ready scheduled claimed blocked failed].freeze
|
|
4
4
|
DISCARDABLE = %w[ready scheduled blocked].freeze
|
|
5
5
|
|
|
6
|
+
before_action :set_status_and_queue, only: [ :destroy, :discard_all ]
|
|
7
|
+
|
|
8
|
+
EXECUTION_MODELS = {
|
|
9
|
+
"ready" => SolidQueue::ReadyExecution,
|
|
10
|
+
"scheduled" => SolidQueue::ScheduledExecution,
|
|
11
|
+
"claimed" => SolidQueue::ClaimedExecution,
|
|
12
|
+
"blocked" => SolidQueue::BlockedExecution,
|
|
13
|
+
"failed" => SolidQueue::FailedExecution
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
6
16
|
def index
|
|
7
17
|
@status = params[:status].presence_in(STATUSES) || "ready"
|
|
8
18
|
@queue = params[:queue].presence
|
|
9
|
-
|
|
10
|
-
@jobs
|
|
11
|
-
when "ready" then SolidQueue::ReadyExecution.includes(:job)
|
|
12
|
-
when "scheduled" then SolidQueue::ScheduledExecution.includes(:job)
|
|
13
|
-
when "claimed" then SolidQueue::ClaimedExecution.includes(:job)
|
|
14
|
-
when "blocked" then SolidQueue::BlockedExecution.includes(:job)
|
|
15
|
-
when "failed" then SolidQueue::FailedExecution.includes(:job)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
@jobs = @jobs.where(jobs: { queue_name: @queue }) if @queue.present?
|
|
19
|
+
@jobs = EXECUTION_MODELS[@status].includes(:job)
|
|
20
|
+
@jobs = @jobs.where(jobs: { queue_name: @queue }) if @queue.present?
|
|
19
21
|
@pagy, @jobs = pagy(@jobs.order(created_at: :desc))
|
|
20
22
|
end
|
|
21
23
|
|
|
@@ -28,27 +30,30 @@ module SolidQueueWeb
|
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
def destroy
|
|
31
|
-
|
|
32
|
-
execution.
|
|
33
|
-
|
|
33
|
+
model = execution_model_for!(@status)
|
|
34
|
+
@execution = model.find(params[:id])
|
|
35
|
+
@execution.discard
|
|
36
|
+
@remaining_count = filtered_scope(model).count
|
|
37
|
+
respond_to do |format|
|
|
38
|
+
format.turbo_stream
|
|
39
|
+
format.html { redirect_to jobs_path(status: @status, queue: @queue), notice: "Job discarded." }
|
|
40
|
+
end
|
|
34
41
|
rescue ArgumentError => e
|
|
35
|
-
redirect_to jobs_path(status:
|
|
42
|
+
redirect_to jobs_path(status: @status, queue: @queue), alert: e.message
|
|
36
43
|
rescue => e
|
|
37
|
-
redirect_to jobs_path(status:
|
|
44
|
+
redirect_to jobs_path(status: @status, queue: @queue), alert: "Could not discard job: #{e.message}"
|
|
38
45
|
end
|
|
39
46
|
|
|
40
47
|
def discard_all
|
|
41
|
-
model = execution_model_for!(
|
|
42
|
-
|
|
43
|
-
scope = scope.where(jobs: { queue_name: params[:queue] }) if params[:queue].present?
|
|
44
|
-
jobs = scope.map(&:job)
|
|
48
|
+
model = execution_model_for!(@status)
|
|
49
|
+
jobs = filtered_scope(model).map(&:job)
|
|
45
50
|
model.discard_all_from_jobs(jobs)
|
|
46
|
-
redirect_to jobs_path(status:
|
|
51
|
+
redirect_to jobs_path(status: @status, queue: @queue),
|
|
47
52
|
notice: "#{jobs.size} #{"job".pluralize(jobs.size)} discarded."
|
|
48
53
|
rescue ArgumentError => e
|
|
49
|
-
redirect_to jobs_path(status:
|
|
54
|
+
redirect_to jobs_path(status: @status, queue: @queue), alert: e.message
|
|
50
55
|
rescue => e
|
|
51
|
-
redirect_to jobs_path(status:
|
|
56
|
+
redirect_to jobs_path(status: @status, queue: @queue), alert: "Could not discard jobs: #{e.message}"
|
|
52
57
|
end
|
|
53
58
|
|
|
54
59
|
private
|
|
@@ -62,13 +67,19 @@ module SolidQueueWeb
|
|
|
62
67
|
"finished"
|
|
63
68
|
end
|
|
64
69
|
|
|
70
|
+
def set_status_and_queue
|
|
71
|
+
@status = params[:status]
|
|
72
|
+
@queue = params[:queue].presence
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def filtered_scope(model)
|
|
76
|
+
scope = model.includes(:job)
|
|
77
|
+
@queue.present? ? scope.where(jobs: { queue_name: @queue }) : scope
|
|
78
|
+
end
|
|
79
|
+
|
|
65
80
|
def execution_model_for!(status)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
when "scheduled" then SolidQueue::ScheduledExecution
|
|
69
|
-
when "blocked" then SolidQueue::BlockedExecution
|
|
70
|
-
else raise ArgumentError, "Cannot discard #{status} jobs from this page."
|
|
71
|
-
end
|
|
81
|
+
raise ArgumentError, "Cannot discard #{status} jobs from this page." unless DISCARDABLE.include?(status)
|
|
82
|
+
EXECUTION_MODELS[status]
|
|
72
83
|
end
|
|
73
84
|
end
|
|
74
85
|
end
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
<h1 class="sqd-page-title">Dashboard</h1>
|
|
2
2
|
|
|
3
3
|
<div class="sqd-stats">
|
|
4
|
-
|
|
4
|
+
<%= link_to jobs_path(status: "ready"), class: "sqd-stat sqd-stat--ready sqd-stat--link" do %>
|
|
5
5
|
<div class="sqd-stat__value"><%= @stats[:ready] %></div>
|
|
6
6
|
<div class="sqd-stat__label">Ready</div>
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
<% end %>
|
|
8
|
+
<%= link_to jobs_path(status: "scheduled"), class: "sqd-stat sqd-stat--scheduled sqd-stat--link" do %>
|
|
9
9
|
<div class="sqd-stat__value"><%= @stats[:scheduled] %></div>
|
|
10
10
|
<div class="sqd-stat__label">Scheduled</div>
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
<% end %>
|
|
12
|
+
<%= link_to jobs_path(status: "claimed"), class: "sqd-stat sqd-stat--claimed sqd-stat--link" do %>
|
|
13
13
|
<div class="sqd-stat__value"><%= @stats[:claimed] %></div>
|
|
14
14
|
<div class="sqd-stat__label">Running</div>
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
<% end %>
|
|
16
|
+
<%= link_to jobs_path(status: "blocked"), class: "sqd-stat sqd-stat--blocked sqd-stat--link" do %>
|
|
17
17
|
<div class="sqd-stat__value"><%= @stats[:blocked] %></div>
|
|
18
18
|
<div class="sqd-stat__label">Blocked</div>
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
<% end %>
|
|
20
|
+
<%= link_to failed_jobs_path, class: "sqd-stat sqd-stat--failed sqd-stat--link" do %>
|
|
21
21
|
<div class="sqd-stat__value"><%= @stats[:failed] %></div>
|
|
22
22
|
<div class="sqd-stat__label">Failed</div>
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
<% end %>
|
|
24
|
+
<%= link_to queues_path, class: "sqd-stat sqd-stat--queues sqd-stat--link" do %>
|
|
25
25
|
<div class="sqd-stat__value"><%= @stats[:queues] %></div>
|
|
26
26
|
<div class="sqd-stat__label">Queues</div>
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
<% end %>
|
|
28
|
+
<%= link_to processes_path, class: "sqd-stat sqd-stat--processes sqd-stat--link" do %>
|
|
29
29
|
<div class="sqd-stat__value"><%= @stats[:processes] %></div>
|
|
30
30
|
<div class="sqd-stat__label">Processes</div>
|
|
31
|
-
|
|
31
|
+
<% end %>
|
|
32
32
|
</div>
|
|
33
33
|
|
|
34
34
|
<div style="display:grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<% if @remaining_count == 0 %>
|
|
2
|
+
<%= turbo_stream.replace "jobs-list" do %>
|
|
3
|
+
<div class="sqd-card" id="jobs-list">
|
|
4
|
+
<div class="sqd-empty">No <%= @status %> jobs.</div>
|
|
5
|
+
</div>
|
|
6
|
+
<% end %>
|
|
7
|
+
<% else %>
|
|
8
|
+
<%= turbo_stream.remove "execution_#{@execution.id}" %>
|
|
9
|
+
<% end %>
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
<h1 class="sqd-page-title" style="margin-bottom: 1.5rem;">Jobs</h1>
|
|
2
|
+
|
|
3
|
+
<%= turbo_frame_tag "jobs-table" do %>
|
|
1
4
|
<% discardable = SolidQueueWeb::JobsController::DISCARDABLE.include?(@status) %>
|
|
2
5
|
|
|
3
6
|
<div class="sqd-page-header">
|
|
4
|
-
<
|
|
7
|
+
<div class="sqd-filters">
|
|
8
|
+
<%= link_to "Ready", jobs_path(status: "ready", queue: @queue), class: @status == "ready" ? "active" : "" %>
|
|
9
|
+
<%= link_to "Scheduled", jobs_path(status: "scheduled", queue: @queue), class: @status == "scheduled" ? "active" : "" %>
|
|
10
|
+
<%= link_to "Running", jobs_path(status: "claimed", queue: @queue), class: @status == "claimed" ? "active" : "" %>
|
|
11
|
+
<%= link_to "Blocked", jobs_path(status: "blocked", queue: @queue), class: @status == "blocked" ? "active" : "" %>
|
|
12
|
+
<%= link_to "Failed", jobs_path(status: "failed", queue: @queue), class: @status == "failed" ? "active" : "" %>
|
|
13
|
+
</div>
|
|
5
14
|
<% if discardable && @jobs.any? %>
|
|
6
15
|
<div class="sqd-actions">
|
|
7
16
|
<%= button_to "Discard All", discard_all_jobs_path,
|
|
@@ -13,15 +22,7 @@
|
|
|
13
22
|
<% end %>
|
|
14
23
|
</div>
|
|
15
24
|
|
|
16
|
-
<div class="sqd-
|
|
17
|
-
<%= link_to "Ready", jobs_path(status: "ready", queue: @queue), class: @status == "ready" ? "active" : "" %>
|
|
18
|
-
<%= link_to "Scheduled", jobs_path(status: "scheduled", queue: @queue), class: @status == "scheduled" ? "active" : "" %>
|
|
19
|
-
<%= link_to "Running", jobs_path(status: "claimed", queue: @queue), class: @status == "claimed" ? "active" : "" %>
|
|
20
|
-
<%= link_to "Blocked", jobs_path(status: "blocked", queue: @queue), class: @status == "blocked" ? "active" : "" %>
|
|
21
|
-
<%= link_to "Failed", jobs_path(status: "failed", queue: @queue), class: @status == "failed" ? "active" : "" %>
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
<div class="sqd-card">
|
|
25
|
+
<div class="sqd-card" id="jobs-list">
|
|
25
26
|
<% if @jobs.empty? %>
|
|
26
27
|
<div class="sqd-empty">No <%= @status %> jobs.</div>
|
|
27
28
|
<% else %>
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
<tbody>
|
|
40
41
|
<% @jobs.each do |execution| %>
|
|
41
42
|
<% job = execution.job %>
|
|
42
|
-
<tr>
|
|
43
|
+
<tr id="execution_<%= execution.id %>">
|
|
43
44
|
<td>
|
|
44
45
|
<span class="sqd-badge sqd-badge--<%= @status %>"><%= @status %></span>
|
|
45
46
|
<%= link_to job.class_name, job_path(job), style: "margin-left: 0.5rem;" %>
|
|
@@ -78,4 +79,5 @@
|
|
|
78
79
|
Filtering by queue: <strong><%= @queue %></strong> —
|
|
79
80
|
<%= link_to "Clear filter", jobs_path(status: @status) %>
|
|
80
81
|
</p>
|
|
82
|
+
<% end %>
|
|
81
83
|
<% end %>
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solid_queue_web
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chuck Smith
|
|
@@ -51,6 +51,20 @@ dependencies:
|
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '43.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: turbo-rails
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '2.0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '2.0'
|
|
54
68
|
description: Mount SolidQueueWeb in any Rails app using Solid Queue to get a dashboard
|
|
55
69
|
for your queues, jobs by status, failed executions, and job actions (retry, discard)
|
|
56
70
|
— all without leaving your app.
|
|
@@ -76,6 +90,7 @@ files:
|
|
|
76
90
|
- app/views/layouts/solid_queue_web/application.html.erb
|
|
77
91
|
- app/views/solid_queue_web/dashboard/index.html.erb
|
|
78
92
|
- app/views/solid_queue_web/failed_jobs/index.html.erb
|
|
93
|
+
- app/views/solid_queue_web/jobs/destroy.turbo_stream.erb
|
|
79
94
|
- app/views/solid_queue_web/jobs/index.html.erb
|
|
80
95
|
- app/views/solid_queue_web/jobs/show.html.erb
|
|
81
96
|
- app/views/solid_queue_web/processes/index.html.erb
|