mission_control-jobs 1.0.1 → 1.1.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 +16 -9
- data/app/assets/stylesheets/mission_control/jobs/bulma.min.css +21012 -2
- data/app/controllers/concerns/mission_control/jobs/job_filters.rb +9 -1
- data/app/controllers/mission_control/jobs/application_controller.rb +1 -0
- data/app/controllers/mission_control/jobs/discards_controller.rb +1 -1
- data/app/controllers/mission_control/jobs/jobs_controller.rb +1 -1
- data/app/controllers/mission_control/jobs/retries_controller.rb +1 -1
- data/app/helpers/mission_control/jobs/application_helper.rb +1 -0
- data/app/helpers/mission_control/jobs/navigation_helper.rb +0 -8
- data/app/views/layouts/mission_control/jobs/_application_selection.html.erb +3 -0
- data/app/views/mission_control/jobs/jobs/_filters.html.erb +34 -24
- data/app/views/mission_control/jobs/jobs/_general_information.html.erb +7 -1
- data/app/views/mission_control/jobs/jobs/blocked/_job.html.erb +3 -2
- data/app/views/mission_control/jobs/jobs/failed/_actions.html.erb +2 -2
- data/app/views/mission_control/jobs/queues/_queue.html.erb +1 -1
- data/lib/active_job/job_proxy.rb +4 -0
- data/lib/active_job/queues.rb +9 -5
- data/lib/mission_control/jobs/engine.rb +7 -12
- data/lib/mission_control/jobs/i18n_config.rb +10 -2
- data/lib/mission_control/jobs/version.rb +1 -1
- metadata +2 -2
@@ -4,7 +4,7 @@ module MissionControl::Jobs::JobFilters
|
|
4
4
|
included do
|
5
5
|
before_action :set_filters
|
6
6
|
|
7
|
-
helper_method :active_filters
|
7
|
+
helper_method :active_filters?, :jobs_filter_param
|
8
8
|
end
|
9
9
|
|
10
10
|
private
|
@@ -20,6 +20,14 @@ module MissionControl::Jobs::JobFilters
|
|
20
20
|
@job_filters.any?
|
21
21
|
end
|
22
22
|
|
23
|
+
def jobs_filter_param
|
24
|
+
if @job_filters&.any?
|
25
|
+
{ filter: @job_filters }
|
26
|
+
else
|
27
|
+
{}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
23
31
|
def finished_at_range_params
|
24
32
|
range_start, range_end = params.dig(:filter, :finished_at_start), params.dig(:filter, :finished_at_end)
|
25
33
|
if range_start || range_end
|
@@ -12,6 +12,7 @@ class MissionControl::Jobs::ApplicationController < MissionControl::Jobs.base_co
|
|
12
12
|
include MissionControl::Jobs::BasicAuthentication
|
13
13
|
include MissionControl::Jobs::ApplicationScoped, MissionControl::Jobs::NotFoundRedirections
|
14
14
|
include MissionControl::Jobs::AdapterFeatures
|
15
|
+
include MissionControl::Jobs::JobFilters
|
15
16
|
|
16
17
|
around_action :set_current_locale
|
17
18
|
|
@@ -13,6 +13,6 @@ class MissionControl::Jobs::DiscardsController < MissionControl::Jobs::Applicati
|
|
13
13
|
|
14
14
|
def redirect_location
|
15
15
|
status = @job.status.presence_in(supported_job_statuses) || :failed
|
16
|
-
application_jobs_url(@application, status)
|
16
|
+
application_jobs_url(@application, status, **jobs_filter_param)
|
17
17
|
end
|
18
18
|
end
|
@@ -3,7 +3,7 @@ class MissionControl::Jobs::RetriesController < MissionControl::Jobs::Applicatio
|
|
3
3
|
|
4
4
|
def create
|
5
5
|
@job.retry
|
6
|
-
redirect_to application_jobs_url(@application, :failed), notice: "Retried job with id #{@job.job_id}"
|
6
|
+
redirect_to application_jobs_url(@application, :failed, **jobs_filter_param), notice: "Retried job with id #{@job.job_id}"
|
7
7
|
end
|
8
8
|
|
9
9
|
private
|
@@ -37,14 +37,6 @@ module MissionControl::Jobs::NavigationHelper
|
|
37
37
|
MissionControl::Jobs::Current.server.name == server.name
|
38
38
|
end
|
39
39
|
|
40
|
-
def jobs_filter_param
|
41
|
-
if @job_filters&.any?
|
42
|
-
{ filter: @job_filters }
|
43
|
-
else
|
44
|
-
{}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
40
|
def jobs_count_with_status(status)
|
49
41
|
count = ActiveJob.jobs.with_status(status).count
|
50
42
|
if count.infinite?
|
@@ -1,6 +1,9 @@
|
|
1
1
|
<nav class="navbar" role="navigation" aria-label="main navigation">
|
2
2
|
<div class="navbar-menu is-active mb-4">
|
3
3
|
<div class="navbar-start">
|
4
|
+
<% if defined?(main_app.root_path) %>
|
5
|
+
<%= link_to "Back to main app", main_app.root_path %>
|
6
|
+
<% end %>
|
4
7
|
</div>
|
5
8
|
|
6
9
|
<div class="navbar-end">
|
@@ -1,45 +1,55 @@
|
|
1
1
|
<div class="filter level-left">
|
2
|
-
|
3
|
-
|
4
|
-
<%= form_for :filter, url: application_jobs_path(MissionControl::Jobs::Current.application, jobs_status), method: :get,
|
5
|
-
data: { controller: "form", action: "input->form#debouncedSubmit" } do |form| %>
|
2
|
+
<%= form_for :filter, url: application_jobs_path(MissionControl::Jobs::Current.application, jobs_status), method: :get,
|
3
|
+
data: { controller: "form", action: "input->form#debouncedSubmit" } do |form| %>
|
6
4
|
|
5
|
+
<div class="field is-grouped">
|
6
|
+
<div class="control">
|
7
|
+
<%= form.label :job_class_name, class: "label" %>
|
7
8
|
<div class="select is-rounded">
|
8
|
-
<%= form.text_field :job_class_name, value: @job_filters[:job_class_name], class: "input", list: "job-classes", placeholder: "Filter by job class..." %>
|
9
|
+
<%= form.text_field :job_class_name, value: @job_filters[:job_class_name], class: "input", list: "job-classes", placeholder: "Filter by job class...", autocomplete: "off" %>
|
9
10
|
</div>
|
11
|
+
</div>
|
10
12
|
|
13
|
+
<div class="control">
|
14
|
+
<%= form.label :queue_name, class: "label" %>
|
11
15
|
<div class="select is-rounded">
|
12
|
-
<%= form.text_field :queue_name, value: @job_filters[:queue_name], class: "input", list: "queue-names", placeholder: "Filter by queue name..." %>
|
16
|
+
<%= form.text_field :queue_name, value: @job_filters[:queue_name], class: "input", list: "queue-names", placeholder: "Filter by queue name...", autocomplete: "off" %>
|
13
17
|
</div>
|
18
|
+
</div>
|
14
19
|
|
15
|
-
|
20
|
+
<% if jobs_status == "finished" %>
|
21
|
+
<div class="control">
|
22
|
+
<%= form.label :finished_at_start, class: "label" %>
|
16
23
|
<div class="select is-rounded">
|
17
24
|
<%= form.datetime_field :finished_at_start, value: @job_filters[:finished_at]&.begin, class: "input", placeholder: "Finished from" %>
|
18
25
|
</div>
|
26
|
+
</div>
|
19
27
|
|
28
|
+
<div class="control">
|
29
|
+
<%= form.label :finished_at_end, class: "label" %>
|
20
30
|
<div class="select is-rounded">
|
21
31
|
<%= form.datetime_field :finished_at_end, value: @job_filters[:finished_at]&.end, class: "input", placeholder: "Finished to" %>
|
22
32
|
</div>
|
23
|
-
|
33
|
+
</div>
|
34
|
+
<% end %>
|
24
35
|
|
25
|
-
|
36
|
+
<%= hidden_field_tag :server_id, MissionControl::Jobs::Current.server.id %>
|
26
37
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
38
|
+
<datalist id="job-classes" class="is-hidden">
|
39
|
+
<% job_class_names.each do |job_class_name| %>
|
40
|
+
<option value="<%= job_class_name %>"></option>
|
41
|
+
<% end %>
|
42
|
+
</datalist>
|
32
43
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
<% end %>
|
39
|
-
</div>
|
44
|
+
<datalist id="queue-names" class="is-hidden">
|
45
|
+
<% queue_names.each do |queue_name| %>
|
46
|
+
<option value="<%= queue_name %>"></option>
|
47
|
+
<% end %>
|
48
|
+
</datalist>
|
40
49
|
|
41
|
-
|
42
|
-
|
50
|
+
<div class="control is-align-self-flex-end">
|
51
|
+
<%= link_to "Clear", application_jobs_path(MissionControl::Jobs::Current.application, jobs_status, job_class_name: nil, queue_name: nil, finished_at: nil..nil), class: "button" %>
|
52
|
+
</div>
|
43
53
|
</div>
|
44
|
-
|
54
|
+
<% end %>
|
45
55
|
</div>
|
@@ -47,11 +47,17 @@
|
|
47
47
|
<% end %>
|
48
48
|
<% if job.finished_at.present? %>
|
49
49
|
<tr>
|
50
|
-
<th>Finished
|
50
|
+
<th>Finished</th>
|
51
51
|
<td>
|
52
52
|
<%= time_distance_in_words_with_title(job.finished_at) %> ago
|
53
53
|
</td>
|
54
54
|
</tr>
|
55
|
+
<tr>
|
56
|
+
<th>Duration</th>
|
57
|
+
<td>
|
58
|
+
<%= job.duration.round(3) %> seconds
|
59
|
+
</td>
|
60
|
+
</tr>
|
55
61
|
<% end %>
|
56
62
|
<% if job.worker_id.present? %>
|
57
63
|
<tr>
|
@@ -1,6 +1,7 @@
|
|
1
1
|
<td><%= link_to job.queue_name, application_queue_path(@application, job.queue) %></td>
|
2
|
-
<td
|
3
|
-
|
2
|
+
<td>
|
3
|
+
<div class="is-family-monospace is-size-7"><%= job.blocked_by %></div>
|
4
|
+
<div class="has-text-grey is-size-7"><%= job.blocked_until ? "Expires #{bidirectional_time_distance_in_words_with_title(job.blocked_until)}" : "" %></div>
|
4
5
|
</td>
|
5
6
|
<td class="pr-0">
|
6
7
|
<%= render "mission_control/jobs/jobs/blocked/actions", job: job %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div class="buttons is-right">
|
2
|
-
<%= button_to "Discard", application_job_discard_path(@application, job.job_id), class: "button is-danger is-light mr-0",
|
2
|
+
<%= button_to "Discard", application_job_discard_path(@application, job.job_id, params: jobs_filter_param), class: "button is-danger is-light mr-0",
|
3
3
|
form: { data: { turbo_confirm: "This will delete the job and can't be undone. Are you sure?" } } %>
|
4
|
-
<%= button_to "Retry", application_job_retry_path(@application, job.job_id), class: "button is-warning is-light mr-0" %>
|
4
|
+
<%= button_to "Retry", application_job_retry_path(@application, job.job_id, params: jobs_filter_param), class: "button is-warning is-light mr-0" %>
|
5
5
|
</div>
|
data/lib/active_job/job_proxy.rb
CHANGED
@@ -24,6 +24,10 @@ class ActiveJob::JobProxy < ActiveJob::Base
|
|
24
24
|
raise UnsupportedError, "A JobProxy doesn't support immediate execution, only enqueuing."
|
25
25
|
end
|
26
26
|
|
27
|
+
def duration
|
28
|
+
finished_at - scheduled_at
|
29
|
+
end
|
30
|
+
|
27
31
|
ActiveJob::JobsRelation::STATUSES.each do |status|
|
28
32
|
define_method "#{status}?" do
|
29
33
|
self.status == status
|
data/lib/active_job/queues.rb
CHANGED
@@ -13,17 +13,21 @@ class ActiveJob::Queues
|
|
13
13
|
include Enumerable
|
14
14
|
|
15
15
|
delegate :each, to: :values
|
16
|
-
delegate :values, to: :
|
17
|
-
delegate :
|
16
|
+
delegate :values, to: :queues_by_id, private: true
|
17
|
+
delegate :size, :length, :to_s, :inspect, to: :queues_by_id
|
18
18
|
|
19
19
|
def initialize(queues)
|
20
|
-
@
|
20
|
+
@queues_by_id = queues.index_by(&:id).with_indifferent_access
|
21
21
|
end
|
22
22
|
|
23
23
|
def to_h
|
24
|
-
|
24
|
+
queues_by_id.dup
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](name)
|
28
|
+
queues_by_id[name.to_s.parameterize]
|
25
29
|
end
|
26
30
|
|
27
31
|
private
|
28
|
-
attr_reader :
|
32
|
+
attr_reader :queues_by_id
|
29
33
|
end
|
@@ -35,8 +35,8 @@ module MissionControl
|
|
35
35
|
end
|
36
36
|
|
37
37
|
initializer "mission_control-jobs.http_basic_auth" do |app|
|
38
|
-
MissionControl::Jobs.http_basic_auth_user
|
39
|
-
MissionControl::Jobs.http_basic_auth_password
|
38
|
+
MissionControl::Jobs.http_basic_auth_user ||= app.credentials.dig(:mission_control, :http_basic_auth_user)
|
39
|
+
MissionControl::Jobs.http_basic_auth_password ||= app.credentials.dig(:mission_control, :http_basic_auth_password)
|
40
40
|
end
|
41
41
|
|
42
42
|
initializer "mission_control-jobs.active_job.extensions" do
|
@@ -63,13 +63,6 @@ module MissionControl
|
|
63
63
|
end
|
64
64
|
|
65
65
|
config.after_initialize do |app|
|
66
|
-
unless app.config.eager_load
|
67
|
-
# When loading classes lazily (development), we want to make sure
|
68
|
-
# the base host +ApplicationController+ class is loaded when loading the
|
69
|
-
# Engine's +ApplicationController+, or it will fail to load the class.
|
70
|
-
MissionControl::Jobs.base_controller_class.constantize
|
71
|
-
end
|
72
|
-
|
73
66
|
if MissionControl::Jobs.applications.empty?
|
74
67
|
queue_adapters_by_name = MissionControl::Jobs.adapters.each_with_object({}) do |adapter, hsh|
|
75
68
|
hsh[adapter] = ActiveJob::QueueAdapters.lookup(adapter).new
|
@@ -103,10 +96,12 @@ module MissionControl
|
|
103
96
|
|
104
97
|
initializer "mission_control-jobs.importmap", after: "importmap" do |app|
|
105
98
|
MissionControl::Jobs.importmap.draw(root.join("config/importmap.rb"))
|
106
|
-
|
99
|
+
if app.config.importmap.sweep_cache && app.config.reloading_enabled?
|
100
|
+
MissionControl::Jobs.importmap.cache_sweeper(watches: root.join("app/javascript"))
|
107
101
|
|
108
|
-
|
109
|
-
|
102
|
+
ActiveSupport.on_load(:action_controller_base) do
|
103
|
+
before_action { MissionControl::Jobs.importmap.cache_sweeper.execute_if_updated }
|
104
|
+
end
|
110
105
|
end
|
111
106
|
end
|
112
107
|
end
|
@@ -1,9 +1,17 @@
|
|
1
1
|
class MissionControl::Jobs::I18nConfig < ::I18n::Config
|
2
|
+
AVAILABLE_LOCALES = [ :en ]
|
3
|
+
AVAILABLE_LOCALES_SET = [ :en, "en" ]
|
4
|
+
DEFAULT_LOCALE = :en
|
5
|
+
|
2
6
|
def available_locales
|
3
|
-
|
7
|
+
AVAILABLE_LOCALES
|
8
|
+
end
|
9
|
+
|
10
|
+
def available_locales_set
|
11
|
+
AVAILABLE_LOCALES_SET
|
4
12
|
end
|
5
13
|
|
6
14
|
def default_locale
|
7
|
-
|
15
|
+
DEFAULT_LOCALE
|
8
16
|
end
|
9
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mission_control-jobs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jorge Manrubia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|