good_job 4.7.0 → 4.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/README.md +30 -1
- data/app/controllers/good_job/metrics_controller.rb +2 -0
- data/app/controllers/good_job/pauses_controller.rb +34 -0
- data/app/controllers/good_job/performance_controller.rb +15 -11
- data/app/models/good_job/job.rb +28 -1
- data/app/models/good_job/setting.rb +78 -0
- data/app/views/good_job/pauses/_group.html.erb +28 -0
- data/app/views/good_job/pauses/_pause.html.erb +8 -0
- data/app/views/good_job/pauses/index.html.erb +46 -0
- data/app/views/good_job/performance/index.html.erb +46 -2
- data/app/views/good_job/shared/_navbar.erb +6 -0
- data/config/locales/de.yml +17 -2
- data/config/locales/en.yml +17 -2
- data/config/locales/es.yml +18 -3
- data/config/locales/fr.yml +35 -20
- data/config/locales/it.yml +19 -4
- data/config/locales/ja.yml +19 -4
- data/config/locales/ko.yml +20 -5
- data/config/locales/nl.yml +21 -6
- data/config/locales/pt-BR.yml +17 -2
- data/config/locales/ru.yml +21 -6
- data/config/locales/tr.yml +19 -4
- data/config/locales/uk.yml +20 -5
- data/config/routes.rb +6 -0
- data/lib/good_job/configuration.rb +12 -0
- data/lib/good_job/scheduler.rb +2 -0
- data/lib/good_job/version.rb +1 -1
- data/lib/good_job.rb +32 -0
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad6949cd77548ff686d2824d654f609567f110b1e778975f72f13aec0eeda672
|
4
|
+
data.tar.gz: bcfa0c1941d237dc5e4a1b8611d1987b1ddef282ac2a4417306f7664032c2c69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36643826c085b2192a63bc917d9271079e6517762d84f0fbf4310e56be6b10eb5d221e53cd526c88668300a3716b527dcfe94cc7f0cc5ba8163503f65770e4e1
|
7
|
+
data.tar.gz: 8fe8418c883034d7e7e008a37b2617b3965582623fd87c034cdc72bd8798c760df3917a3e5b4e2d0cf9d2caa255cfe3924f0e97b4c110f361c61b00d55fa99db
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,39 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v4.8.1](https://github.com/bensheldon/good_job/tree/v4.8.1) (2025-01-24)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v4.8.0...v4.8.1)
|
6
|
+
|
7
|
+
**Fixed bugs:**
|
8
|
+
|
9
|
+
- Fix notifier/scheduler handling of integer/epoch serialized scheduled\_at values [\#1583](https://github.com/bensheldon/good_job/pull/1583) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
|
11
|
+
**Closed issues:**
|
12
|
+
|
13
|
+
- Losing "Processes" on the dashboard [\#1582](https://github.com/bensheldon/good_job/issues/1582)
|
14
|
+
- Notifier errored: TypeError: ActiveSupport::TimeWithZone can't be coerced into Integer [\#1581](https://github.com/bensheldon/good_job/issues/1581)
|
15
|
+
- Ability to pause queues [\#1574](https://github.com/bensheldon/good_job/issues/1574)
|
16
|
+
|
17
|
+
## [v4.8.0](https://github.com/bensheldon/good_job/tree/v4.8.0) (2025-01-22)
|
18
|
+
|
19
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v4.7.0...v4.8.0)
|
20
|
+
|
21
|
+
**Implemented enhancements:**
|
22
|
+
|
23
|
+
- Add ability to pause jobs by queue, job class, or label \(experimental\) [\#1575](https://github.com/bensheldon/good_job/pull/1575) ([bensheldon](https://github.com/bensheldon))
|
24
|
+
|
25
|
+
**Closed issues:**
|
26
|
+
|
27
|
+
- perform\_now enqueues a job when raising exception [\#1570](https://github.com/bensheldon/good_job/issues/1570)
|
28
|
+
|
29
|
+
**Merged pull requests:**
|
30
|
+
|
31
|
+
- Use Ruby 3.4.1 for development [\#1579](https://github.com/bensheldon/good_job/pull/1579) ([bensheldon](https://github.com/bensheldon))
|
32
|
+
- Fix generator tests [\#1577](https://github.com/bensheldon/good_job/pull/1577) ([bensheldon](https://github.com/bensheldon))
|
33
|
+
- Add the logger gem as a dependency to fix rails head [\#1576](https://github.com/bensheldon/good_job/pull/1576) ([bensheldon](https://github.com/bensheldon))
|
34
|
+
- fix: typo in en.yml when discarding jobs [\#1569](https://github.com/bensheldon/good_job/pull/1569) ([nickstanish](https://github.com/nickstanish))
|
35
|
+
- Bump the all group with 60 updates [\#1567](https://github.com/bensheldon/good_job/pull/1567) ([dependabot[bot]](https://github.com/apps/dependabot))
|
36
|
+
|
3
37
|
## [v4.7.0](https://github.com/bensheldon/good_job/tree/v4.7.0) (2024-12-31)
|
4
38
|
|
5
39
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v4.6.0...v4.7.0)
|
data/README.md
CHANGED
@@ -73,6 +73,7 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
|
|
73
73
|
- [Write tests](#write-tests)
|
74
74
|
- [PgBouncer compatibility](#pgbouncer-compatibility)
|
75
75
|
- [CLI HTTP health check probes](#cli-http-health-check-probes)
|
76
|
+
- [Pausing Jobs](#pausing-jobs)
|
76
77
|
- [Doing your best job with GoodJob](#doing-your-best-job-with-goodjob)
|
77
78
|
- [Sizing jobs: mice and elephants](#sizing-jobs-mice-and-elephants)
|
78
79
|
- [Isolating by total latency](#isolating-by-total-latency)
|
@@ -329,6 +330,8 @@ Available configuration options are:
|
|
329
330
|
config.good_job.probe_handler = 'webrick'
|
330
331
|
```
|
331
332
|
|
333
|
+
- `enable_pauses` (boolean) whether job processing can be paused. Defaults to `false`. You can also set this with the environment variable `GOOD_JOB_ENABLE_PAUSES`.
|
334
|
+
|
332
335
|
By default, GoodJob configures the following execution modes per environment:
|
333
336
|
|
334
337
|
```ruby
|
@@ -1559,9 +1562,35 @@ gem 'webrick'
|
|
1559
1562
|
|
1560
1563
|
If WEBrick is configured to be used, but the dependency is not found, GoodJob will log a warning and fallback to the default probe server.
|
1561
1564
|
|
1565
|
+
### Pausing Jobs
|
1566
|
+
|
1567
|
+
GoodJob allows for pausing jobs by queue or job class. This feature is currently opt-in because the performance impact of loading and filtering these attributes is not yet known. To enable this feature, add the following to your configuration:
|
1568
|
+
|
1569
|
+
> ```ruby
|
1570
|
+
> config.good_job.enable_pauses = true
|
1571
|
+
> ```
|
1572
|
+
|
1573
|
+
Pausing can be done via the Dashboard's Performance page, or in Ruby
|
1574
|
+
|
1575
|
+
```ruby
|
1576
|
+
# To pause:
|
1577
|
+
GoodJob.pause(queue: "default")
|
1578
|
+
GoodJob.pause(job_class: "MyJob")
|
1579
|
+
|
1580
|
+
# To check status
|
1581
|
+
GoodJob.paused # => { queues: ["default"], job_classes: ["MyJob"] }
|
1582
|
+
GoodJob.paused?(queue: "default") # => true
|
1583
|
+
GoodJob.paused?(job_class: "MyJob") # => true
|
1584
|
+
GoodJob.paused? # => true
|
1585
|
+
|
1586
|
+
# To unpause
|
1587
|
+
GoodJob.unpause(queue: "default")
|
1588
|
+
GoodJob.unpause(job_class: "MyJob")
|
1589
|
+
````
|
1590
|
+
|
1562
1591
|
## Doing your best job with GoodJob
|
1563
1592
|
|
1564
|
-
_This section explains how to use GoodJob the most efficiently and performantly, according to its maintainers. GoodJob is very flexible and you don
|
1593
|
+
_This section explains how to use GoodJob the most efficiently and performantly, according to its maintainers. GoodJob is very flexible and you don't necessarily have to use it this way, but the concepts explained here are part of GoodJob's design intent._
|
1565
1594
|
|
1566
1595
|
Background jobs are hard. There are two extremes:
|
1567
1596
|
|
@@ -6,6 +6,7 @@ module GoodJob
|
|
6
6
|
jobs_count = GoodJob::Job.count
|
7
7
|
batches_count = GoodJob::BatchRecord.all.size
|
8
8
|
cron_entries_count = GoodJob::CronEntry.all.size
|
9
|
+
pauses_count = GoodJob::Setting.paused.values.sum(&:count)
|
9
10
|
processes_count = GoodJob::Process.active.count
|
10
11
|
discarded_count = GoodJob::Job.discarded.count
|
11
12
|
|
@@ -13,6 +14,7 @@ module GoodJob
|
|
13
14
|
jobs_count: helpers.number_to_human(jobs_count),
|
14
15
|
batches_count: helpers.number_to_human(batches_count),
|
15
16
|
cron_entries_count: helpers.number_to_human(cron_entries_count),
|
17
|
+
pauses_count: helpers.number_to_human(pauses_count),
|
16
18
|
processes_count: helpers.number_to_human(processes_count),
|
17
19
|
discarded_count: helpers.number_to_human(discarded_count),
|
18
20
|
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GoodJob
|
4
|
+
class PausesController < ApplicationController
|
5
|
+
before_action :validate_type, only: [:create, :destroy]
|
6
|
+
def index
|
7
|
+
@paused = GoodJob::Setting.paused
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
pause_type = params[:type].to_sym
|
12
|
+
pause_value = params[:value].to_s
|
13
|
+
|
14
|
+
GoodJob::Setting.pause(pause_type => pause_value)
|
15
|
+
redirect_to({ action: :index }, notice: "Successfully paused #{params[:type]} '#{params[:value]}'")
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
pause_type = params[:type].to_sym
|
20
|
+
pause_value = params[:value].to_s
|
21
|
+
|
22
|
+
GoodJob::Setting.unpause(pause_type => pause_value)
|
23
|
+
redirect_to({ action: :index }, notice: "Successfully unpaused #{params[:type]} '#{params[:value]}'")
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def validate_type
|
29
|
+
return if params[:type].in?(%w[queue job_class label]) && params[:value].to_s.present?
|
30
|
+
|
31
|
+
raise ActionController::BadRequest, "Invalid type"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -3,17 +3,21 @@
|
|
3
3
|
module GoodJob
|
4
4
|
class PerformanceController < ApplicationController
|
5
5
|
def index
|
6
|
-
@performances = GoodJob::Execution
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
@performances = GoodJob::Execution.group(:job_class).select("
|
7
|
+
job_class,
|
8
|
+
COUNT(*) AS executions_count,
|
9
|
+
AVG(duration) AS avg_duration,
|
10
|
+
MIN(duration) AS min_duration,
|
11
|
+
MAX(duration) AS max_duration
|
12
|
+
").order(:job_class)
|
13
|
+
|
14
|
+
@queue_performances = GoodJob::Execution.group(:queue_name).select("
|
15
|
+
queue_name,
|
16
|
+
COUNT(*) AS executions_count,
|
17
|
+
AVG(duration) AS avg_duration,
|
18
|
+
MIN(duration) AS min_duration,
|
19
|
+
MAX(duration) AS max_duration
|
20
|
+
").order(:queue_name)
|
17
21
|
end
|
18
22
|
|
19
23
|
def show
|
data/app/models/good_job/job.rb
CHANGED
@@ -96,6 +96,33 @@ module GoodJob
|
|
96
96
|
# @return [ActiveRecord::Relation]
|
97
97
|
scope :only_scheduled, -> { where(arel_table['scheduled_at'].lteq(bind_value('scheduled_at', DateTime.current, ActiveRecord::Type::DateTime))).or(where(scheduled_at: nil)) }
|
98
98
|
|
99
|
+
# Exclude jobs that are paused via queue_name or job_class.
|
100
|
+
# Only applies when enable_pauses configuration is true.
|
101
|
+
# @!method exclude_paused
|
102
|
+
# @!scope class
|
103
|
+
# @return [ActiveRecord::Relation]
|
104
|
+
scope :exclude_paused, lambda {
|
105
|
+
return all unless GoodJob.configuration.enable_pauses
|
106
|
+
|
107
|
+
paused_query = GoodJob::Setting.where(key: GoodJob::Setting::PAUSES)
|
108
|
+
paused_queues_query = paused_query.select("jsonb_array_elements_text(value->'queues')")
|
109
|
+
paused_job_classes_query = paused_query.select("jsonb_array_elements_text(value->'job_classes')")
|
110
|
+
paused_labels_query = paused_query.select("jsonb_array_elements_text(value->'labels')")
|
111
|
+
|
112
|
+
where.not(queue_name: paused_queues_query)
|
113
|
+
.where.not(job_class: paused_job_classes_query)
|
114
|
+
.where(
|
115
|
+
Arel::Nodes::Not.new(
|
116
|
+
Arel::Nodes::NamedFunction.new(
|
117
|
+
"COALESCE", [
|
118
|
+
Arel::Nodes::InfixOperation.new('&&', arel_table['labels'], Arel::Nodes::NamedFunction.new('ARRAY', [paused_labels_query.arel])),
|
119
|
+
Arel::Nodes::SqlLiteral.new('FALSE'),
|
120
|
+
]
|
121
|
+
)
|
122
|
+
)
|
123
|
+
)
|
124
|
+
}
|
125
|
+
|
99
126
|
# Order jobs by priority (highest priority first).
|
100
127
|
# @!method priority_ordered
|
101
128
|
# @!scope class
|
@@ -290,7 +317,7 @@ module GoodJob
|
|
290
317
|
job = nil
|
291
318
|
result = nil
|
292
319
|
|
293
|
-
unfinished.dequeueing_ordered(parsed_queues).only_scheduled.limit(1).with_advisory_lock(select_limit: queue_select_limit) do |jobs|
|
320
|
+
unfinished.dequeueing_ordered(parsed_queues).only_scheduled.exclude_paused.limit(1).with_advisory_lock(select_limit: queue_select_limit) do |jobs|
|
294
321
|
job = jobs.first
|
295
322
|
|
296
323
|
if job&.executable?
|
@@ -4,6 +4,7 @@ module GoodJob
|
|
4
4
|
class Setting < BaseRecord
|
5
5
|
CRON_KEYS_ENABLED = "cron_keys_enabled"
|
6
6
|
CRON_KEYS_DISABLED = "cron_keys_disabled"
|
7
|
+
PAUSES = "pauses"
|
7
8
|
|
8
9
|
self.table_name = 'good_job_settings'
|
9
10
|
self.implicit_order_column = 'created_at'
|
@@ -47,5 +48,82 @@ module GoodJob
|
|
47
48
|
disabled_setting.value << key unless disabled_setting.value.include?(key_string)
|
48
49
|
disabled_setting.save!
|
49
50
|
end
|
51
|
+
|
52
|
+
def self.pause(queue: nil, job_class: nil, label: nil)
|
53
|
+
raise ArgumentError, "Must provide exactly one of queue, job_class, or label" unless [queue, job_class, label].count(&:present?) == 1
|
54
|
+
|
55
|
+
setting = find_or_initialize_by(key: PAUSES) do |record|
|
56
|
+
record.value = { "queues" => [], "job_classes" => [], "labels" => [] }
|
57
|
+
end
|
58
|
+
|
59
|
+
if queue
|
60
|
+
setting.value["queues"] ||= []
|
61
|
+
setting.value["queues"] << queue.to_s unless setting.value["queues"].include?(queue.to_s)
|
62
|
+
elsif job_class
|
63
|
+
setting.value["job_classes"] ||= []
|
64
|
+
setting.value["job_classes"] << job_class.to_s unless setting.value["job_classes"].include?(job_class.to_s)
|
65
|
+
else
|
66
|
+
setting.value["labels"] ||= []
|
67
|
+
setting.value["labels"] << label.to_s unless setting.value["labels"].include?(label.to_s)
|
68
|
+
end
|
69
|
+
setting.save!
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.unpause(queue: nil, job_class: nil, label: nil)
|
73
|
+
raise ArgumentError, "Must provide exactly one of queue, job_class, or label" unless [queue, job_class, label].count(&:present?) == 1
|
74
|
+
|
75
|
+
setting = find_by(key: PAUSES)
|
76
|
+
return unless setting
|
77
|
+
|
78
|
+
if queue
|
79
|
+
return unless setting.value["queues"]&.include?(queue.to_s)
|
80
|
+
|
81
|
+
setting.value["queues"].delete(queue.to_s)
|
82
|
+
elsif job_class
|
83
|
+
return unless setting.value["job_classes"]&.include?(job_class.to_s)
|
84
|
+
|
85
|
+
setting.value["job_classes"].delete(job_class.to_s)
|
86
|
+
else
|
87
|
+
return unless setting.value["labels"]&.include?(label.to_s)
|
88
|
+
|
89
|
+
setting.value["labels"].delete(label.to_s)
|
90
|
+
end
|
91
|
+
setting.save!
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.paused?(queue: nil, job_class: nil, label: nil)
|
95
|
+
raise ArgumentError, "Must provide at most one of queue, job_class, or label" if [queue, job_class, label].count(&:present?) > 1
|
96
|
+
|
97
|
+
if queue
|
98
|
+
queue.in? paused(:queues)
|
99
|
+
elsif job_class
|
100
|
+
job_class.in? paused(:job_classes)
|
101
|
+
elsif label
|
102
|
+
label.in? paused(:labels)
|
103
|
+
else
|
104
|
+
paused.values.any?(&:any?)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.paused(type = nil)
|
109
|
+
setting = find_by(key: PAUSES)
|
110
|
+
pauses = setting&.value&.deep_dup || { "queues" => [], "job_classes" => [], "labels" => [] }
|
111
|
+
pauses = pauses.with_indifferent_access
|
112
|
+
|
113
|
+
case type
|
114
|
+
when :queues
|
115
|
+
pauses["queues"]
|
116
|
+
when :job_classes
|
117
|
+
pauses["job_classes"]
|
118
|
+
when :labels
|
119
|
+
pauses["labels"]
|
120
|
+
else
|
121
|
+
{
|
122
|
+
queues: pauses["queues"] || [],
|
123
|
+
job_classes: pauses["job_classes"] || [],
|
124
|
+
labels: pauses["labels"] || [],
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
50
128
|
end
|
51
129
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<% group = type.to_s.pluralize.to_sym %>
|
2
|
+
<% items = paused.fetch(group) { [] } %>
|
3
|
+
<% if items&.any? %>
|
4
|
+
<div class="my-3 card">
|
5
|
+
<div class="list-group list-group-flush text-nowrap" role="table">
|
6
|
+
<header class="list-group-item bg-body-tertiary">
|
7
|
+
<div class="row small text-muted text-uppercase align-items-center">
|
8
|
+
<div class="col-12"><%= t("good_job.pauses.index.#{type}") %></div>
|
9
|
+
</div>
|
10
|
+
</header>
|
11
|
+
|
12
|
+
<% items.each do |value| %>
|
13
|
+
<li class="list-group-item d-flex justify-content-between align-items-center">
|
14
|
+
<%= value %>
|
15
|
+
<%= button_to(
|
16
|
+
{ action: :destroy, type: type, value: value },
|
17
|
+
method: :delete,
|
18
|
+
class: 'btn btn-sm btn-outline-primary',
|
19
|
+
data: { confirm: t('good_job.pauses.index.confirm_unpause', value: value) }
|
20
|
+
) do %>
|
21
|
+
<%= render_icon "play" %>
|
22
|
+
<%= t("good_job.pauses.index.unpause") %>
|
23
|
+
<% end %>
|
24
|
+
</li>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
<% end %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<li class="list-group-item d-flex justify-content-between align-items-center">
|
2
|
+
<%= value %>
|
3
|
+
<%= button_to t('good_job.pauses.index.unpause'),
|
4
|
+
{ action: :destroy, type: type, value: value },
|
5
|
+
method: :delete,
|
6
|
+
class: 'btn btn-sm btn-outline-primary',
|
7
|
+
data: { confirm: t('good_job.pauses.index.confirm_unpause', value: value) } %>
|
8
|
+
</li>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<%= content_for :page_title do %>
|
2
|
+
<%= t('good_job.pauses.index.title') %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<div class="border-bottom">
|
6
|
+
<h1 class="h2 pt-3 pb-2"><%= t('good_job.pauses.index.title') %></h1>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<% if GoodJob.configuration.enable_pauses %>
|
10
|
+
<div class="card mb-4">
|
11
|
+
<div class="card-body">
|
12
|
+
<%= form_tag({ action: :create }, method: :post, class: 'row g-3 align-items-end') do %>
|
13
|
+
<div class="col-3">
|
14
|
+
<%= label_tag :type, t('good_job.pauses.index.type'), class: 'form-label' %>
|
15
|
+
<%= select_tag :type,
|
16
|
+
options_for_select([
|
17
|
+
[t('good_job.pauses.index.queue'), 'queue'],
|
18
|
+
[t('good_job.pauses.index.job_class'), 'job_class'],
|
19
|
+
[t('good_job.pauses.index.label'), 'label'],
|
20
|
+
]),
|
21
|
+
class: 'form-select',
|
22
|
+
required: true %>
|
23
|
+
</div>
|
24
|
+
<div class="col-6">
|
25
|
+
<%= label_tag :value, t('good_job.pauses.index.value'), class: 'form-label' %>
|
26
|
+
<%= text_field_tag :value, nil, class: 'form-control', autocomplete: "off", required: true %>
|
27
|
+
</div>
|
28
|
+
<div class="col-3">
|
29
|
+
<%= button_tag type: "submit", class: 'btn btn-primary' do %>
|
30
|
+
<%= render_icon "pause" %>
|
31
|
+
<%= t('good_job.pauses.index.pause', value: '') %>
|
32
|
+
<% end %>
|
33
|
+
</div>
|
34
|
+
<% end %>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<%= render 'group', paused: @paused, type: :queue %>
|
39
|
+
<%= render 'group', paused: @paused, type: :job_class %>
|
40
|
+
<%= render 'group', paused: @paused, type: :label %>
|
41
|
+
<% else %>
|
42
|
+
<div class="alert alert-warning" role="alert">
|
43
|
+
<p><%= t('good_job.pauses.index.disabled') %>:</p>
|
44
|
+
<pre class="mb-0">config.good_job.enable_pauses = true</pre>
|
45
|
+
</div>
|
46
|
+
<% end %>
|
@@ -10,7 +10,6 @@
|
|
10
10
|
<div class="row small text-muted text-uppercase align-items-center">
|
11
11
|
<div class="col-12 col-lg-4"><%= t ".job_class" %></div>
|
12
12
|
<div class="col-lg-2 d-none d-lg-block"><%= t ".executions" %></div>
|
13
|
-
|
14
13
|
<div class="col-lg-2 d-none d-lg-block"><%= t ".average_duration" %></div>
|
15
14
|
<div class="col-lg-2 d-none d-lg-block"><%= t ".minimum_duration" %></div>
|
16
15
|
<div class="col-lg-2 d-none d-lg-block"><%= t ".maximum_duration" %></div>
|
@@ -20,12 +19,57 @@
|
|
20
19
|
<% @performances.each do |performance| %>
|
21
20
|
<div role="row" class="list-group-item py-3">
|
22
21
|
<div class="row align-items-center">
|
23
|
-
<div class="col-12 col-lg-4"
|
22
|
+
<div class="col-12 col-lg-4">
|
23
|
+
<div class="d-flex gap-3 justify-content-between">
|
24
|
+
<%= link_to performance.job_class, performance_path(performance.job_class) %>
|
25
|
+
</div>
|
26
|
+
</div>
|
24
27
|
<div class="col-6 col-lg-2 text-wrap">
|
25
28
|
<div class="d-lg-none small text-muted mt-1"><%= t ".executions" %></div>
|
26
29
|
<%= performance.executions_count %>
|
27
30
|
</div>
|
31
|
+
<div class="col-6 col-lg-2 text-wrap">
|
32
|
+
<div class="d-lg-none small text-muted mt-1"><%= t ".average_duration" %></div>
|
33
|
+
<%= format_duration performance.avg_duration %>
|
34
|
+
</div>
|
35
|
+
<div class="col-6 col-lg-2 text-wrap">
|
36
|
+
<div class="d-lg-none small text-muted mt-1"><%= t ".minimum_duration" %></div>
|
37
|
+
<%= format_duration performance.min_duration %>
|
38
|
+
</div>
|
39
|
+
<div class="col-6 col-lg-2 text-wrap">
|
40
|
+
<div class="d-lg-none small text-muted mt-1"><%= t ".maximum_duration" %></div>
|
41
|
+
<%= format_duration performance.max_duration %>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
</div>
|
28
48
|
|
49
|
+
<div class="my-3 card">
|
50
|
+
<div class="list-group list-group-flush text-nowrap" role="table">
|
51
|
+
<header class="list-group-item bg-body-tertiary">
|
52
|
+
<div class="row small text-muted text-uppercase align-items-center">
|
53
|
+
<div class="col-12 col-lg-4"><%= t ".queue_name" %></div>
|
54
|
+
<div class="col-lg-2 d-none d-lg-block"><%= t ".executions" %></div>
|
55
|
+
<div class="col-lg-2 d-none d-lg-block"><%= t ".average_duration" %></div>
|
56
|
+
<div class="col-lg-2 d-none d-lg-block"><%= t ".minimum_duration" %></div>
|
57
|
+
<div class="col-lg-2 d-none d-lg-block"><%= t ".maximum_duration" %></div>
|
58
|
+
</div>
|
59
|
+
</header>
|
60
|
+
|
61
|
+
<% @queue_performances.each do |performance| %>
|
62
|
+
<div role="row" class="list-group-item py-3">
|
63
|
+
<div class="row align-items-center">
|
64
|
+
<div class="col-12 col-lg-4">
|
65
|
+
<div class="d-flex gap-3 justify-content-between">
|
66
|
+
<%= performance.queue_name %>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
<div class="col-6 col-lg-2 text-wrap">
|
70
|
+
<div class="d-lg-none small text-muted mt-1"><%= t ".executions" %></div>
|
71
|
+
<%= performance.executions_count %>
|
72
|
+
</div>
|
29
73
|
<div class="col-6 col-lg-2 text-wrap">
|
30
74
|
<div class="d-lg-none small text-muted mt-1"><%= t ".average_duration" %></div>
|
31
75
|
<%= format_duration performance.avg_duration %>
|
@@ -44,6 +44,12 @@
|
|
44
44
|
<%= t(".performance") %>
|
45
45
|
<% end %>
|
46
46
|
</li>
|
47
|
+
<li class="nav-item">
|
48
|
+
<%= link_to pauses_path, class: ["nav-link", ("active" if controller_name == 'pauses')] do %>
|
49
|
+
<%= t(".pauses") %>
|
50
|
+
<span data-async-values-target="value" data-async-values-key="pauses_count" data-async-values-zero-class="d-none" class="badge bg-warning rounded-pill d-none"></span>
|
51
|
+
<% end %>
|
52
|
+
</li>
|
47
53
|
<li class="nav-item">
|
48
54
|
<%= link_to cleaner_index_path, class: ["nav-link", ("active" if controller_name == 'cleaner')] do %>
|
49
55
|
<%= t(".cleaner") %>
|
data/config/locales/de.yml
CHANGED
@@ -214,14 +214,28 @@ de:
|
|
214
214
|
thousand: K
|
215
215
|
trillion: T
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: Sind Sie sicher, dass Sie %{value} pausieren möchten?
|
220
|
+
confirm_unpause: Sind Sie sicher, dass Sie %{value} fortsetzen möchten?
|
221
|
+
disabled: Die experimentelle Pausenfunktion von GoodJob ist standardmäßig deaktiviert, da sie die Leistung beeinträchtigen kann. Konfigurieren Sie sie zur Aktivierung
|
222
|
+
job_class: Job-Klasse
|
223
|
+
label: Label
|
224
|
+
pause: Pausieren
|
225
|
+
queue: Warteschlange
|
226
|
+
title: Pausen
|
227
|
+
type: Pausentyp
|
228
|
+
unpause: Fortsetzen
|
229
|
+
value: Wert
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: Durchschnittliche Dauer
|
220
|
-
chart_title:
|
233
|
+
chart_title: Gesamtausführungszeit in Sekunden
|
221
234
|
executions: Ausführungen
|
222
235
|
job_class: Job-Klasse
|
223
236
|
maximum_duration: Maximale Dauer
|
224
|
-
minimum_duration:
|
237
|
+
minimum_duration: Minimale Dauer
|
238
|
+
queue_name: Warteschlangenname
|
225
239
|
title: Leistung
|
226
240
|
show:
|
227
241
|
slow: Langsam
|
@@ -256,6 +270,7 @@ de:
|
|
256
270
|
jobs: Jobs
|
257
271
|
live_poll: Live Poll
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: Pausen
|
259
274
|
performance: Leistung
|
260
275
|
processes: Prozesse
|
261
276
|
theme:
|
data/config/locales/en.yml
CHANGED
@@ -127,7 +127,7 @@ en:
|
|
127
127
|
jobs:
|
128
128
|
actions:
|
129
129
|
confirm_destroy: Are you sure you want to destroy the job?
|
130
|
-
confirm_discard: Are you
|
130
|
+
confirm_discard: Are you sure you want to discard the job?
|
131
131
|
confirm_force_discard: Are you sure you want to force discard this job? The job will be marked as discarded but the running job will not be stopped - it will, however, not be retried on failures.
|
132
132
|
confirm_reschedule: Are you sure you want to reschedule the job?
|
133
133
|
confirm_retry: Are you sure you want to retry the job?
|
@@ -163,7 +163,7 @@ en:
|
|
163
163
|
one: Apply to all 1 job.
|
164
164
|
other: Apply to all %{count} jobs.
|
165
165
|
confirm_destroy_all: Are you sure you want to destroy the selected jobs?
|
166
|
-
confirm_discard_all: Are you
|
166
|
+
confirm_discard_all: Are you sure you want to discard the selected jobs?
|
167
167
|
confirm_reschedule_all: Are you sure you want to reschedule the selected jobs?
|
168
168
|
confirm_retry_all: Are you sure you want to retry the selected jobs?
|
169
169
|
destroy_all: Destroy all
|
@@ -214,6 +214,19 @@ en:
|
|
214
214
|
thousand: K
|
215
215
|
trillion: T
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: Are you sure you want to pause %{value}?
|
220
|
+
confirm_unpause: Are you sure you want to resume %{value}?
|
221
|
+
disabled: GoodJob's experimental Pauses feature is disabled by default because it may degrade performance. Configure to enable
|
222
|
+
job_class: Job Class
|
223
|
+
label: Label
|
224
|
+
pause: Pause
|
225
|
+
queue: Queue
|
226
|
+
title: Pauses
|
227
|
+
type: Pause Type
|
228
|
+
unpause: Resume
|
229
|
+
value: Value
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: Average duration
|
@@ -222,6 +235,7 @@ en:
|
|
222
235
|
job_class: Job class
|
223
236
|
maximum_duration: Maximum duration
|
224
237
|
minimum_duration: Minimum duration
|
238
|
+
queue_name: Queue name
|
225
239
|
title: Performance
|
226
240
|
show:
|
227
241
|
slow: Slow
|
@@ -256,6 +270,7 @@ en:
|
|
256
270
|
jobs: Jobs
|
257
271
|
live_poll: Live Poll
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: Pauses
|
259
274
|
performance: Performance
|
260
275
|
processes: Processes
|
261
276
|
theme:
|
data/config/locales/es.yml
CHANGED
@@ -214,18 +214,32 @@ es:
|
|
214
214
|
thousand: k
|
215
215
|
trillion: T
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: "¿Está seguro de que desea pausar %{value}?"
|
220
|
+
confirm_unpause: "¿Está seguro de que desea reanudar %{value}?"
|
221
|
+
disabled: La función experimental de Pausas de GoodJob está desactivada por defecto porque puede degradar el rendimiento. Configure para habilitar
|
222
|
+
job_class: Clase de trabajo
|
223
|
+
label: Etiqueta
|
224
|
+
pause: Pausar
|
225
|
+
queue: Cola
|
226
|
+
title: Pausas
|
227
|
+
type: Tipo de Pausa
|
228
|
+
unpause: Reanudar
|
229
|
+
value: Valor
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: Duración promedio
|
220
|
-
chart_title: Tiempo total de ejecución
|
233
|
+
chart_title: Tiempo total de ejecución del trabajo en segundos
|
221
234
|
executions: Ejecuciones
|
222
|
-
job_class:
|
235
|
+
job_class: Clase de trabajo
|
223
236
|
maximum_duration: Duración máxima
|
224
237
|
minimum_duration: Duración mínima
|
238
|
+
queue_name: Nombre de la cola
|
225
239
|
title: Rendimiento
|
226
240
|
show:
|
227
241
|
slow: Lento
|
228
|
-
title:
|
242
|
+
title: Rendimiento
|
229
243
|
processes:
|
230
244
|
index:
|
231
245
|
cron_enabled: Cron habilitado
|
@@ -256,6 +270,7 @@ es:
|
|
256
270
|
jobs: Tareas
|
257
271
|
live_poll: En vivo
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: Pausas
|
259
274
|
performance: Rendimiento
|
260
275
|
processes: Procesos
|
261
276
|
theme:
|
data/config/locales/fr.yml
CHANGED
@@ -10,17 +10,17 @@ fr:
|
|
10
10
|
retry: Recommencez
|
11
11
|
batches:
|
12
12
|
actions:
|
13
|
-
confirm_retry: Voulez-vous vraiment réessayer ce lot
|
13
|
+
confirm_retry: Voulez-vous vraiment réessayer ce lot ?
|
14
14
|
retry: Réessayer
|
15
15
|
index:
|
16
16
|
older_batches: Lots plus anciens
|
17
17
|
title: Lots
|
18
18
|
jobs:
|
19
19
|
actions:
|
20
|
-
confirm_destroy: Voulez-vous vraiment détruire ce job
|
21
|
-
confirm_discard: Voulez-vous vraiment mettre au rebut ce job
|
22
|
-
confirm_reschedule: Voulez-vous vraiment replanifier ce job
|
23
|
-
confirm_retry: Voulez-vous vraiment réessayer ce job
|
20
|
+
confirm_destroy: Voulez-vous vraiment détruire ce job ?
|
21
|
+
confirm_discard: Voulez-vous vraiment mettre au rebut ce job ?
|
22
|
+
confirm_reschedule: Voulez-vous vraiment replanifier ce job ?
|
23
|
+
confirm_retry: Voulez-vous vraiment réessayer ce job ?
|
24
24
|
destroy: Détruire le job
|
25
25
|
discard: Mettre au rebut le job
|
26
26
|
reschedule: Replanifier le job
|
@@ -51,9 +51,9 @@ fr:
|
|
51
51
|
total: Total
|
52
52
|
cron_entries:
|
53
53
|
actions:
|
54
|
-
confirm_disable: Voulez-vous vraiment désactiver cette entrée cron
|
55
|
-
confirm_enable: Voulez-vous vraiment activer cette entrée cron
|
56
|
-
confirm_enqueue: Voulez-vous vraiment mettre en file d'attente cette entrée cron
|
54
|
+
confirm_disable: Voulez-vous vraiment désactiver cette entrée cron ?
|
55
|
+
confirm_enable: Voulez-vous vraiment activer cette entrée cron ?
|
56
|
+
confirm_enqueue: Voulez-vous vraiment mettre en file d'attente cette entrée cron ?
|
57
57
|
disable: Désactiver l'entrée cron
|
58
58
|
enable: Activer l'entrée cron
|
59
59
|
enqueue: Mettre en file d'attente l'entrée cron maintenant
|
@@ -126,11 +126,11 @@ fr:
|
|
126
126
|
past: il y a %{time}
|
127
127
|
jobs:
|
128
128
|
actions:
|
129
|
-
confirm_destroy: Voulez-vous vraiment détruire le job
|
130
|
-
confirm_discard: Voulez-vous vraiment mettre au rebut le job
|
129
|
+
confirm_destroy: Voulez-vous vraiment détruire le job ?
|
130
|
+
confirm_discard: Voulez-vous vraiment mettre au rebut le job ?
|
131
131
|
confirm_force_discard: Êtes-vous sûr de vouloir forcer l'abandon du travail? Le travail sera marqué comme abandonné mais le travail en cours ne sera pas arrêté - cependant, il ne sera pas réessayé en cas d'échec.
|
132
|
-
confirm_reschedule: Voulez-vous vraiment replanifier le job
|
133
|
-
confirm_retry: Voulez-vous vraiment réessayer le job
|
132
|
+
confirm_reschedule: Voulez-vous vraiment replanifier le job ?
|
133
|
+
confirm_retry: Voulez-vous vraiment réessayer le job ?
|
134
134
|
destroy: Détruire le job
|
135
135
|
discard: Mettre au rebut le job
|
136
136
|
force_discard: Forcer l'abandon du travail
|
@@ -162,10 +162,10 @@ fr:
|
|
162
162
|
apply_to_all:
|
163
163
|
one: Appliquer à ce job
|
164
164
|
other: Appliquer aux %{count} jobs
|
165
|
-
confirm_destroy_all: Voulez-vous vraiment détruire les jobs sélectionnés
|
166
|
-
confirm_discard_all: Voulez-vous vraiment mettre au rebut les jobs sélectionnés
|
167
|
-
confirm_reschedule_all: Voulez-vous vraiment replanifier les jobs sélectionnées
|
168
|
-
confirm_retry_all: Voulez-vous vraiment réessayer les jobs sélectionnées
|
165
|
+
confirm_destroy_all: Voulez-vous vraiment détruire les jobs sélectionnés ?
|
166
|
+
confirm_discard_all: Voulez-vous vraiment mettre au rebut les jobs sélectionnés ?
|
167
|
+
confirm_reschedule_all: Voulez-vous vraiment replanifier les jobs sélectionnées ?
|
168
|
+
confirm_retry_all: Voulez-vous vraiment réessayer les jobs sélectionnées ?
|
169
169
|
destroy_all: Tout détruire
|
170
170
|
discard_all: Tout mettre au rebut
|
171
171
|
reschedule_all: Tout replanifier
|
@@ -214,17 +214,31 @@ fr:
|
|
214
214
|
thousand: k
|
215
215
|
trillion: J
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: Êtes-vous sûr de vouloir mettre en pause %{value} ?
|
220
|
+
confirm_unpause: Êtes-vous sûr de vouloir reprendre %{value} ?
|
221
|
+
disabled: La fonction expérimentale de Pauses de GoodJob est désactivée par défaut car elle peut dégrader les performances. Configurez pour activer
|
222
|
+
job_class: Classe de tâche
|
223
|
+
label: Étiquette
|
224
|
+
pause: Pause
|
225
|
+
queue: File d'attente
|
226
|
+
title: Pauses
|
227
|
+
type: Type de Pause
|
228
|
+
unpause: Reprendre
|
229
|
+
value: Valeur
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: Durée moyenne
|
220
|
-
chart_title:
|
233
|
+
chart_title: Temps total d'exécution des tâches en secondes
|
221
234
|
executions: Exécutions
|
222
|
-
job_class:
|
235
|
+
job_class: Classe de tâche
|
223
236
|
maximum_duration: Durée maximale
|
224
237
|
minimum_duration: Durée minimale
|
238
|
+
queue_name: Nom de la file
|
225
239
|
title: Performance
|
226
240
|
show:
|
227
|
-
slow:
|
241
|
+
slow: Lent
|
228
242
|
title: Performance
|
229
243
|
processes:
|
230
244
|
index:
|
@@ -256,6 +270,7 @@ fr:
|
|
256
270
|
jobs: Jobs
|
257
271
|
live_poll: En direct
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: Pauses
|
259
274
|
performance: Performance
|
260
275
|
processes: Processus
|
261
276
|
theme:
|
@@ -265,7 +280,7 @@ fr:
|
|
265
280
|
theme: Thème
|
266
281
|
pending_migrations: GoodJob a des migrations de bases de données en attente.
|
267
282
|
secondary_navbar:
|
268
|
-
inspiration: N'oublie pas, toi aussi tu fais du bon boulot
|
283
|
+
inspiration: N'oublie pas, toi aussi tu fais du bon boulot !
|
269
284
|
last_updated: Dernière mise à jour
|
270
285
|
status:
|
271
286
|
discarded: Mis au rebut
|
data/config/locales/it.yml
CHANGED
@@ -214,18 +214,32 @@ it:
|
|
214
214
|
thousand: K
|
215
215
|
trillion: T
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: Sei sicuro di voler mettere in pausa %{value}?
|
220
|
+
confirm_unpause: Sei sicuro di voler riprendere %{value}?
|
221
|
+
disabled: La funzione sperimentale Pause di GoodJob è disabilitata per impostazione predefinita perché potrebbe degradare le prestazioni. Configurare per abilitare
|
222
|
+
job_class: Classe del job
|
223
|
+
label: Etichetta
|
224
|
+
pause: Pausa
|
225
|
+
queue: Coda
|
226
|
+
title: Pause
|
227
|
+
type: Tipo di Pausa
|
228
|
+
unpause: Riprendi
|
229
|
+
value: Valore
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: Durata media
|
220
|
-
chart_title: Tempo totale di esecuzione
|
233
|
+
chart_title: Tempo totale di esecuzione in secondi
|
221
234
|
executions: Esecuzioni
|
222
|
-
job_class: Classe
|
235
|
+
job_class: Classe del job
|
223
236
|
maximum_duration: Durata massima
|
224
237
|
minimum_duration: Durata minima
|
225
|
-
|
238
|
+
queue_name: Nome della coda
|
239
|
+
title: Prestazioni
|
226
240
|
show:
|
227
241
|
slow: Lento
|
228
|
-
title:
|
242
|
+
title: Prestazioni
|
229
243
|
processes:
|
230
244
|
index:
|
231
245
|
cron_enabled: Cron abilitato
|
@@ -256,6 +270,7 @@ it:
|
|
256
270
|
jobs: Job
|
257
271
|
live_poll: Live Poll
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: Pause
|
259
274
|
performance: Prestazione
|
260
275
|
processes: Processi
|
261
276
|
theme:
|
data/config/locales/ja.yml
CHANGED
@@ -214,14 +214,28 @@ ja:
|
|
214
214
|
thousand: K
|
215
215
|
trillion: T
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: "%{value}を一時停止してもよろしいですか?"
|
220
|
+
confirm_unpause: "%{value}を再開してもよろしいですか?"
|
221
|
+
disabled: GoodJobの実験的な一時停止機能は、パフォーマンスが低下する可能性があるため、デフォルトでは無効になっています。有効にするには設定してください
|
222
|
+
job_class: ジョブクラス
|
223
|
+
label: ラベル
|
224
|
+
pause: 一時停止
|
225
|
+
queue: キュー
|
226
|
+
title: 一時停止
|
227
|
+
type: 一時停止タイプ
|
228
|
+
unpause: 再開
|
229
|
+
value: 値
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: 平均所要時間
|
220
|
-
chart_title:
|
221
|
-
executions:
|
233
|
+
chart_title: 合計実行時間(秒)
|
234
|
+
executions: 実行回数
|
222
235
|
job_class: ジョブクラス
|
223
|
-
maximum_duration:
|
224
|
-
minimum_duration:
|
236
|
+
maximum_duration: 最大所要時間
|
237
|
+
minimum_duration: 最小所要時間
|
238
|
+
queue_name: キュー名
|
225
239
|
title: パフォーマンス
|
226
240
|
show:
|
227
241
|
slow: 遅い
|
@@ -256,6 +270,7 @@ ja:
|
|
256
270
|
jobs: ジョブ
|
257
271
|
live_poll: リアルタイム更新
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: 一時停止
|
259
274
|
performance: パフォーマンス
|
260
275
|
processes: プロセス
|
261
276
|
theme:
|
data/config/locales/ko.yml
CHANGED
@@ -214,14 +214,28 @@ ko:
|
|
214
214
|
thousand: K
|
215
215
|
trillion: T
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: "%{value}를 일시 중지하시겠습니까?"
|
220
|
+
confirm_unpause: "%{value}를 재개하시겠습니까?"
|
221
|
+
disabled: GoodJob의 실험적인 일시 중지 기능은 성능이 저하될 수 있으므로 기본적으로 비활성화되어 있습니다. 활성화하려면 구성하세요
|
222
|
+
job_class: 작업 클래스
|
223
|
+
label: 라벨
|
224
|
+
pause: 일시 중지
|
225
|
+
queue: 대기열
|
226
|
+
title: 일시 중지
|
227
|
+
type: 중지 유형
|
228
|
+
unpause: 재개
|
229
|
+
value: 값
|
217
230
|
performance:
|
218
231
|
index:
|
219
|
-
average_duration: 평균
|
220
|
-
chart_title: 총
|
221
|
-
executions: 실행
|
232
|
+
average_duration: 평균 소요 시간
|
233
|
+
chart_title: 총 실행 시간(초)
|
234
|
+
executions: 실행 횟수
|
222
235
|
job_class: 작업 클래스
|
223
|
-
maximum_duration: 최대
|
224
|
-
minimum_duration: 최소
|
236
|
+
maximum_duration: 최대 소요 시간
|
237
|
+
minimum_duration: 최소 소요 시간
|
238
|
+
queue_name: 큐 이름
|
225
239
|
title: 성능
|
226
240
|
show:
|
227
241
|
slow: 느림
|
@@ -256,6 +270,7 @@ ko:
|
|
256
270
|
jobs: 작업
|
257
271
|
live_poll: 실시간 업데이트
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: 일시 중지
|
259
274
|
performance: 성능
|
260
275
|
processes: 프로세스
|
261
276
|
theme:
|
data/config/locales/nl.yml
CHANGED
@@ -214,18 +214,32 @@ nl:
|
|
214
214
|
thousand: K
|
215
215
|
trillion: T
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: Weet u zeker dat u %{value} wilt pauzeren?
|
220
|
+
confirm_unpause: Weet u zeker dat u %{value} wilt hervatten?
|
221
|
+
disabled: De experimentele Pauzes-functie van GoodJob is standaard uitgeschakeld omdat het de prestaties kan verminderen. Configureer om in te schakelen
|
222
|
+
job_class: Taakklasse
|
223
|
+
label: Label
|
224
|
+
pause: Pauzeren
|
225
|
+
queue: Wachtrij
|
226
|
+
title: Pauzes
|
227
|
+
type: Pauze Type
|
228
|
+
unpause: Hervatten
|
229
|
+
value: Waarde
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: Gemiddelde duur
|
220
|
-
chart_title: Totale uitvoeringstijd
|
221
|
-
executions:
|
222
|
-
job_class:
|
233
|
+
chart_title: Totale uitvoeringstijd in seconden
|
234
|
+
executions: Uitvoeringen
|
235
|
+
job_class: Taakklasse
|
223
236
|
maximum_duration: Maximale duur
|
224
237
|
minimum_duration: Minimale duur
|
225
|
-
|
238
|
+
queue_name: Wachtrijnaam
|
239
|
+
title: Prestaties
|
226
240
|
show:
|
227
|
-
slow:
|
228
|
-
title:
|
241
|
+
slow: Traag
|
242
|
+
title: Prestaties
|
229
243
|
processes:
|
230
244
|
index:
|
231
245
|
cron_enabled: Cron ingeschakeld
|
@@ -256,6 +270,7 @@ nl:
|
|
256
270
|
jobs: Taken
|
257
271
|
live_poll: Live Poll
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: Pauzes
|
259
274
|
performance: Prestatie
|
260
275
|
processes: Processen
|
261
276
|
theme:
|
data/config/locales/pt-BR.yml
CHANGED
@@ -214,14 +214,28 @@ pt-BR:
|
|
214
214
|
thousand: K
|
215
215
|
trillion: T
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: Tem certeza que deseja pausar %{value}?
|
220
|
+
confirm_unpause: Tem certeza que deseja retomar %{value}?
|
221
|
+
disabled: O recurso experimental de Pausas do GoodJob está desativado por padrão porque pode degradar o desempenho. Configure para ativar
|
222
|
+
job_class: Classe do trabalho
|
223
|
+
label: Rótulo
|
224
|
+
pause: Pausar
|
225
|
+
queue: Fila
|
226
|
+
title: Pausas
|
227
|
+
type: Tipo de Pausa
|
228
|
+
unpause: Retomar
|
229
|
+
value: Valor
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: Duração média
|
220
|
-
chart_title: Tempo total de execução
|
233
|
+
chart_title: Tempo total de execução em segundos
|
221
234
|
executions: Execuções
|
222
|
-
job_class: Classe
|
235
|
+
job_class: Classe do trabalho
|
223
236
|
maximum_duration: Duração máxima
|
224
237
|
minimum_duration: Duração mínima
|
238
|
+
queue_name: Nome da fila
|
225
239
|
title: Desempenho
|
226
240
|
show:
|
227
241
|
slow: Lento
|
@@ -256,6 +270,7 @@ pt-BR:
|
|
256
270
|
jobs: Tarefas
|
257
271
|
live_poll: Acompanhamento ao Vivo
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: Pausas
|
259
274
|
performance: Desempenho
|
260
275
|
processes: Processos
|
261
276
|
theme:
|
data/config/locales/ru.yml
CHANGED
@@ -240,17 +240,31 @@ ru:
|
|
240
240
|
thousand: К
|
241
241
|
trillion: Т
|
242
242
|
unit: ''
|
243
|
+
pauses:
|
244
|
+
index:
|
245
|
+
confirm_pause: Вы уверены, что хотите приостановить %{value}?
|
246
|
+
confirm_unpause: Вы уверены, что хотите возобновить %{value}?
|
247
|
+
disabled: Экспериментальная функция Паузы в GoodJob отключена по умолчанию, так как это может снизить производительность. Настройте для включения
|
248
|
+
job_class: Класс задачи
|
249
|
+
label: Метка
|
250
|
+
pause: Приостановить
|
251
|
+
queue: Очередь
|
252
|
+
title: Паузы
|
253
|
+
type: Тип Паузы
|
254
|
+
unpause: Возобновить
|
255
|
+
value: Значение
|
243
256
|
performance:
|
244
257
|
index:
|
245
258
|
average_duration: Средняя продолжительность
|
246
|
-
chart_title: Общее время выполнения
|
247
|
-
executions:
|
248
|
-
job_class: Класс
|
259
|
+
chart_title: Общее время выполнения в секундах
|
260
|
+
executions: Выполнения
|
261
|
+
job_class: Класс задачи
|
249
262
|
maximum_duration: Максимальная продолжительность
|
250
263
|
minimum_duration: Минимальная продолжительность
|
264
|
+
queue_name: Название очереди
|
251
265
|
title: Производительность
|
252
266
|
show:
|
253
|
-
slow:
|
267
|
+
slow: Медленно
|
254
268
|
title: Производительность
|
255
269
|
processes:
|
256
270
|
index:
|
@@ -276,12 +290,13 @@ ru:
|
|
276
290
|
queue_name: Название очереди
|
277
291
|
search: Поиск
|
278
292
|
navbar:
|
279
|
-
batches:
|
293
|
+
batches: Пакеты
|
280
294
|
cleaner: Discard Cleaner
|
281
295
|
cron_schedules: Cron
|
282
296
|
jobs: Задания
|
283
|
-
live_poll:
|
297
|
+
live_poll: Живой опрос
|
284
298
|
name: "GoodJob 👍"
|
299
|
+
pauses: Паузы
|
285
300
|
performance: Производительность
|
286
301
|
processes: Процессы
|
287
302
|
theme:
|
data/config/locales/tr.yml
CHANGED
@@ -214,18 +214,32 @@ tr:
|
|
214
214
|
thousand: Bin
|
215
215
|
trillion: Trilyon
|
216
216
|
unit: ''
|
217
|
+
pauses:
|
218
|
+
index:
|
219
|
+
confirm_pause: "%{value} duraklatmak istediğinizden emin misiniz?"
|
220
|
+
confirm_unpause: "%{value} devam ettirmek istediğinizden emin misiniz?"
|
221
|
+
disabled: GoodJob'ın deneysel Duraklatma özelliği, performansı düşürebileceği için varsayılan olarak devre dışıdır. Etkinleştirmek için yapılandırın
|
222
|
+
job_class: İş sınıfı
|
223
|
+
label: Etiket
|
224
|
+
pause: Duraklat
|
225
|
+
queue: Kuyruk
|
226
|
+
title: Duraklatmalar
|
227
|
+
type: Duraklatma Türü
|
228
|
+
unpause: Devam Et
|
229
|
+
value: Değer
|
217
230
|
performance:
|
218
231
|
index:
|
219
232
|
average_duration: Ortalama süre
|
220
|
-
chart_title:
|
221
|
-
executions:
|
233
|
+
chart_title: Toplam yürütme süresi (saniye)
|
234
|
+
executions: Yürütmeler
|
222
235
|
job_class: İş sınıfı
|
223
236
|
maximum_duration: Maksimum süre
|
224
237
|
minimum_duration: Minimum süre
|
225
|
-
|
238
|
+
queue_name: Kuyruk adı
|
239
|
+
title: Performans
|
226
240
|
show:
|
227
241
|
slow: Yavaş
|
228
|
-
title:
|
242
|
+
title: Performans
|
229
243
|
processes:
|
230
244
|
index:
|
231
245
|
cron_enabled: Cron etkin
|
@@ -256,6 +270,7 @@ tr:
|
|
256
270
|
jobs: İşler
|
257
271
|
live_poll: Anlık Güncelleme
|
258
272
|
name: "GoodJob 👍"
|
273
|
+
pauses: Duraklatmalar
|
259
274
|
performance: Verim
|
260
275
|
processes: Süreçler
|
261
276
|
theme:
|
data/config/locales/uk.yml
CHANGED
@@ -240,14 +240,28 @@ uk:
|
|
240
240
|
thousand: Тис
|
241
241
|
trillion: Трлн
|
242
242
|
unit: ''
|
243
|
+
pauses:
|
244
|
+
index:
|
245
|
+
confirm_pause: Ви впевнені, що хочете призупинити %{value}?
|
246
|
+
confirm_unpause: Ви впевнені, що хочете відновити %{value}?
|
247
|
+
disabled: Експериментальна функція Паузи в GoodJob вимкнена за замовчуванням, оскільки це може знизити продуктивність. Налаштуйте для увімкнення
|
248
|
+
job_class: Клас завдання
|
249
|
+
label: Мітка
|
250
|
+
pause: Призупинити
|
251
|
+
queue: Черга
|
252
|
+
title: Паузи
|
253
|
+
type: Тип Паузи
|
254
|
+
unpause: Відновити
|
255
|
+
value: Значення
|
243
256
|
performance:
|
244
257
|
index:
|
245
258
|
average_duration: Середня тривалість
|
246
|
-
chart_title: Загальний час виконання
|
247
|
-
executions:
|
248
|
-
job_class: Клас
|
259
|
+
chart_title: Загальний час виконання в секундах
|
260
|
+
executions: Виконання
|
261
|
+
job_class: Клас завдання
|
249
262
|
maximum_duration: Максимальна тривалість
|
250
263
|
minimum_duration: Мінімальна тривалість
|
264
|
+
queue_name: Назва черги
|
251
265
|
title: Продуктивність
|
252
266
|
show:
|
253
267
|
slow: Повільно
|
@@ -279,9 +293,10 @@ uk:
|
|
279
293
|
batches: Пакети
|
280
294
|
cleaner: Discard Cleaner
|
281
295
|
cron_schedules: Cron
|
282
|
-
jobs:
|
283
|
-
live_poll: Живе
|
296
|
+
jobs: Роботи
|
297
|
+
live_poll: Живе опитування
|
284
298
|
name: "GoodJob 👍"
|
299
|
+
pauses: Паузи
|
285
300
|
performance: Продуктивність
|
286
301
|
processes: Процеси
|
287
302
|
theme:
|
data/config/routes.rb
CHANGED
@@ -35,6 +35,12 @@ GoodJob::Engine.routes.draw do
|
|
35
35
|
|
36
36
|
resources :processes, only: %i[index]
|
37
37
|
resources :performance, only: %i[index show]
|
38
|
+
resources :pauses, only: %i[index] do
|
39
|
+
collection do
|
40
|
+
post :create
|
41
|
+
delete :destroy
|
42
|
+
end
|
43
|
+
end
|
38
44
|
resources :cleaner, only: %i[index]
|
39
45
|
|
40
46
|
scope :frontend, controller: :frontends, defaults: { version: GoodJob::VERSION.tr(".", "-") } do
|
@@ -35,6 +35,8 @@ module GoodJob
|
|
35
35
|
DEFAULT_DASHBOARD_LIVE_POLL_ENABLED = true
|
36
36
|
# Default enqueue_after_transaction_commit
|
37
37
|
DEFAULT_ENQUEUE_AFTER_TRANSACTION_COMMIT = false
|
38
|
+
# Default enable_pauses setting
|
39
|
+
DEFAULT_ENABLE_PAUSES = false
|
38
40
|
|
39
41
|
def self.validate_execution_mode(execution_mode)
|
40
42
|
raise ArgumentError, "GoodJob execution mode must be one of #{EXECUTION_MODES.join(', ')}. It was '#{execution_mode}' which is not valid." unless execution_mode.in?(EXECUTION_MODES)
|
@@ -369,6 +371,16 @@ module GoodJob
|
|
369
371
|
DEFAULT_ENQUEUE_AFTER_TRANSACTION_COMMIT
|
370
372
|
end
|
371
373
|
|
374
|
+
# Whether the job processing can be paused.
|
375
|
+
# @return [Boolean]
|
376
|
+
def enable_pauses
|
377
|
+
return options[:enable_pauses] unless options[:enable_pauses].nil?
|
378
|
+
return rails_config[:enable_pauses] unless rails_config[:enable_pauses].nil?
|
379
|
+
return ActiveModel::Type::Boolean.new.cast(env['GOOD_JOB_ENABLE_PAUSES']) unless env['GOOD_JOB_ENABLE_PAUSE'].nil?
|
380
|
+
|
381
|
+
DEFAULT_ENABLE_PAUSES
|
382
|
+
end
|
383
|
+
|
372
384
|
# Whether running in a web server process.
|
373
385
|
# @return [Boolean, nil]
|
374
386
|
def in_webserver?
|
data/lib/good_job/scheduler.rb
CHANGED
@@ -162,6 +162,8 @@ module GoodJob # :nodoc:
|
|
162
162
|
if state[:scheduled_at]
|
163
163
|
scheduled_at = if state[:scheduled_at].is_a? String
|
164
164
|
Time.zone.parse state[:scheduled_at]
|
165
|
+
elsif state[:scheduled_at].is_a? Numeric
|
166
|
+
Time.zone.at state[:scheduled_at]
|
165
167
|
else
|
166
168
|
state[:scheduled_at]
|
167
169
|
end
|
data/lib/good_job/version.rb
CHANGED
data/lib/good_job.rb
CHANGED
@@ -292,6 +292,38 @@ module GoodJob
|
|
292
292
|
def self.migrated?
|
293
293
|
GoodJob::BatchRecord.jobs_finished_at_migrated?
|
294
294
|
end
|
295
|
+
|
296
|
+
# Pause job execution for a given queue or job class.
|
297
|
+
# @param queue [String, nil] Queue name to pause
|
298
|
+
# @param job_class [String, nil] Job class name to pause
|
299
|
+
# @return [void]
|
300
|
+
def self.pause(queue: nil, job_class: nil)
|
301
|
+
GoodJob::Setting.pause(queue: queue, job_class: job_class)
|
302
|
+
end
|
303
|
+
|
304
|
+
# Unpause job execution for a given queue or job class.
|
305
|
+
# @param queue [String, nil] Queue name to unpause
|
306
|
+
# @param job_class [String, nil] Job class name to unpause
|
307
|
+
# @param label [String, nil] Label to unpause
|
308
|
+
# @return [void]
|
309
|
+
def self.unpause(queue: nil, job_class: nil, label: nil)
|
310
|
+
GoodJob::Setting.unpause(queue: queue, job_class: job_class, label: label)
|
311
|
+
end
|
312
|
+
|
313
|
+
# Check if job execution is paused for a given queue or job class.
|
314
|
+
# @param queue [String, nil] Queue name to check
|
315
|
+
# @param job_class [String, nil] Job class name to check
|
316
|
+
# @param label [String, nil] Label to check
|
317
|
+
# @return [Boolean]
|
318
|
+
def self.paused?(queue: nil, job_class: nil, label: nil)
|
319
|
+
GoodJob::Setting.paused?(queue: queue, job_class: job_class, label: label)
|
320
|
+
end
|
321
|
+
|
322
|
+
# Get a list of all paused queues and job classes
|
323
|
+
# @return [Hash] Hash with :queues, :job_classes, :labels arrays of paused items
|
324
|
+
def self.paused(type = nil)
|
325
|
+
GoodJob::Setting.paused(type)
|
326
|
+
end
|
295
327
|
end
|
296
328
|
|
297
329
|
ActiveSupport.run_load_hooks(:good_job, GoodJob)
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: good_job
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Sheldon
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-01-24 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activejob
|
@@ -259,6 +258,7 @@ files:
|
|
259
258
|
- app/controllers/good_job/frontends_controller.rb
|
260
259
|
- app/controllers/good_job/jobs_controller.rb
|
261
260
|
- app/controllers/good_job/metrics_controller.rb
|
261
|
+
- app/controllers/good_job/pauses_controller.rb
|
262
262
|
- app/controllers/good_job/performance_controller.rb
|
263
263
|
- app/controllers/good_job/processes_controller.rb
|
264
264
|
- app/filters/good_job/base_filter.rb
|
@@ -313,6 +313,9 @@ files:
|
|
313
313
|
- app/views/good_job/jobs/_table.erb
|
314
314
|
- app/views/good_job/jobs/index.html.erb
|
315
315
|
- app/views/good_job/jobs/show.html.erb
|
316
|
+
- app/views/good_job/pauses/_group.html.erb
|
317
|
+
- app/views/good_job/pauses/_pause.html.erb
|
318
|
+
- app/views/good_job/pauses/index.html.erb
|
316
319
|
- app/views/good_job/performance/index.html.erb
|
317
320
|
- app/views/good_job/performance/show.html.erb
|
318
321
|
- app/views/good_job/processes/index.html.erb
|
@@ -396,7 +399,6 @@ metadata:
|
|
396
399
|
homepage_uri: https://github.com/bensheldon/good_job
|
397
400
|
source_code_uri: https://github.com/bensheldon/good_job
|
398
401
|
rubygems_mfa_required: 'true'
|
399
|
-
post_install_message:
|
400
402
|
rdoc_options:
|
401
403
|
- "--title"
|
402
404
|
- GoodJob - a multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
|
@@ -418,8 +420,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
418
420
|
- !ruby/object:Gem::Version
|
419
421
|
version: '0'
|
420
422
|
requirements: []
|
421
|
-
rubygems_version: 3.
|
422
|
-
signing_key:
|
423
|
+
rubygems_version: 3.6.2
|
423
424
|
specification_version: 4
|
424
425
|
summary: A multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
|
425
426
|
test_files: []
|