good_job 3.16.3 → 3.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -0
- data/README.md +41 -15
- data/app/frontend/good_job/application.js +2 -0
- data/app/frontend/good_job/modules/theme_controller.js +44 -0
- data/app/frontend/good_job/vendor/bootstrap/bootstrap.bundle.min.js +3 -3
- data/app/frontend/good_job/vendor/bootstrap/bootstrap.min.css +3 -4
- data/app/models/concerns/good_job/{lockable.rb → advisory_lockable.rb} +1 -1
- data/app/models/good_job/base_execution.rb +24 -1
- data/app/models/good_job/batch.rb +2 -2
- data/app/models/good_job/batch_record.rb +1 -1
- data/app/models/good_job/execution.rb +0 -21
- data/app/models/good_job/process.rb +5 -1
- data/app/views/good_job/batches/_jobs.erb +3 -3
- data/app/views/good_job/batches/_table.erb +1 -1
- data/app/views/good_job/batches/show.html.erb +1 -1
- data/app/views/good_job/cron_entries/index.html.erb +2 -2
- data/app/views/good_job/jobs/_executions.erb +2 -2
- data/app/views/good_job/jobs/_table.erb +10 -9
- data/app/views/good_job/jobs/show.html.erb +2 -2
- data/app/views/good_job/processes/index.html.erb +3 -3
- data/app/views/good_job/shared/_footer.erb +1 -1
- data/app/views/good_job/shared/_navbar.erb +50 -7
- data/app/views/good_job/shared/icons/_circle_half.html.erb +4 -0
- data/app/views/good_job/shared/icons/_moon_stars_fill.html.erb +5 -0
- data/app/views/good_job/shared/icons/_sun_fill.html.erb +4 -0
- data/app/views/layouts/good_job/application.html.erb +9 -1
- data/config/locales/de.yml +5 -0
- data/config/locales/en.yml +5 -0
- data/config/locales/es.yml +5 -0
- data/config/locales/fr.yml +5 -0
- data/config/locales/ja.yml +5 -0
- data/config/locales/nl.yml +5 -0
- data/config/locales/ru.yml +5 -0
- data/config/locales/tr.yml +5 -0
- data/config/locales/uk.yml +5 -0
- data/lib/good_job/capsule.rb +5 -4
- data/lib/good_job/cli.rb +6 -2
- data/lib/good_job/configuration.rb +2 -5
- data/lib/good_job/cron_manager.rb +3 -2
- data/lib/good_job/http_server.rb +75 -0
- data/lib/good_job/log_subscriber.rb +18 -0
- data/lib/good_job/notifier.rb +59 -44
- data/lib/good_job/probe_server.rb +4 -8
- data/lib/good_job/sd_notify.rb +157 -0
- data/lib/good_job/shared_executor.rb +69 -0
- data/lib/good_job/systemd_service.rb +69 -0
- data/lib/good_job/version.rb +1 -1
- data/lib/good_job.rb +6 -0
- metadata +11 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 946d6d7912809cf31d3f79c0dc7e2c074b20c7bcd853d6c3a9ab35faa5f4f6aa
|
4
|
+
data.tar.gz: d33a7a41a7c8c259d71c5e8caa7fb268ec0db2c7516a4fb45d937c4e05d5fb64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e849433834f758352c918379f1c727d3b992cd6843f9f27de4768d2f7845402f5c9b418cb93da285811df55882d0a0a6acac90bcedf1bdeac9dbafca66e7af54
|
7
|
+
data.tar.gz: fe3ae7523b7d9307a085a298a771301b3d9707495a24866eec113bbc172a83ffedfe68e452c1b925e0e04f2a5a54175a995c2c312f1f3033e860615182015c2a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,53 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v3.17.0](https://github.com/bensheldon/good_job/tree/v3.17.0) (2023-08-06)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.16.4...v3.17.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Add Dark Mode color theme for Dashboard [\#1031](https://github.com/bensheldon/good_job/pull/1031) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
- Automatically send status notifications to systemd [\#1029](https://github.com/bensheldon/good_job/pull/1029) ([Mr0grog](https://github.com/Mr0grog))
|
11
|
+
|
12
|
+
**Closed issues:**
|
13
|
+
|
14
|
+
- Add systemd/sd\_notify support to CLI [\#1027](https://github.com/bensheldon/good_job/issues/1027)
|
15
|
+
- Cron job by default runs on the web server even when "async" execution mode is not specified [\#1026](https://github.com/bensheldon/good_job/issues/1026)
|
16
|
+
- Replace webrick with a small/simple custom rack-compatible http server [\#1017](https://github.com/bensheldon/good_job/issues/1017)
|
17
|
+
- Dark mode for the dashboard ? [\#974](https://github.com/bensheldon/good_job/issues/974)
|
18
|
+
|
19
|
+
**Merged pull requests:**
|
20
|
+
|
21
|
+
- Replace Webrick with custom simple http server [\#1030](https://github.com/bensheldon/good_job/pull/1030) ([dixpac](https://github.com/dixpac))
|
22
|
+
- Bump appraisal from `b200e63` to `feb78bc` [\#1025](https://github.com/bensheldon/good_job/pull/1025) ([dependabot[bot]](https://github.com/apps/dependabot))
|
23
|
+
- Bump net-imap from 0.3.6 to 0.3.7 [\#1024](https://github.com/bensheldon/good_job/pull/1024) ([dependabot[bot]](https://github.com/apps/dependabot))
|
24
|
+
- Bump rack from 2.2.7 to 2.2.8 [\#1023](https://github.com/bensheldon/good_job/pull/1023) ([dependabot[bot]](https://github.com/apps/dependabot))
|
25
|
+
|
26
|
+
## [v3.16.4](https://github.com/bensheldon/good_job/tree/v3.16.4) (2023-07-30)
|
27
|
+
|
28
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.16.3...v3.16.4)
|
29
|
+
|
30
|
+
**Implemented enhancements:**
|
31
|
+
|
32
|
+
- Add database\_connection\_pool stats to `GoodJob::Process.current_state` [\#1019](https://github.com/bensheldon/good_job/pull/1019) ([dixpac](https://github.com/dixpac))
|
33
|
+
|
34
|
+
**Fixed bugs:**
|
35
|
+
|
36
|
+
- Move `Execution#active_job` to BaseExecution to share with Job; refactor `Batch#active_jobs` to use job directly [\#1022](https://github.com/bensheldon/good_job/pull/1022) ([bensheldon](https://github.com/bensheldon))
|
37
|
+
|
38
|
+
**Closed issues:**
|
39
|
+
|
40
|
+
- Notifier errored: ArgumentError: wrong number of arguments \(given 1, expected 0\) [\#1016](https://github.com/bensheldon/good_job/issues/1016)
|
41
|
+
- Understanding Database Connections and Cron [\#1013](https://github.com/bensheldon/good_job/issues/1013)
|
42
|
+
- Experiencing various database exceptions with Rails 7.1 [\#796](https://github.com/bensheldon/good_job/issues/796)
|
43
|
+
|
44
|
+
**Merged pull requests:**
|
45
|
+
|
46
|
+
- Refactor Notifier to ensure \#restart is threadsafe [\#1021](https://github.com/bensheldon/good_job/pull/1021) ([bensheldon](https://github.com/bensheldon))
|
47
|
+
- Notifier and CronManager share a 2-thread executor within the capsule [\#1018](https://github.com/bensheldon/good_job/pull/1018) ([bensheldon](https://github.com/bensheldon))
|
48
|
+
- Clarify database connections and recurring processes in README.md [\#1015](https://github.com/bensheldon/good_job/pull/1015) ([blumhardts](https://github.com/blumhardts))
|
49
|
+
- Deprecate `GoodJob::Lockable` and rename to `GoodJob::AdvisoryLockable` [\#1012](https://github.com/bensheldon/good_job/pull/1012) ([bensheldon](https://github.com/bensheldon))
|
50
|
+
|
3
51
|
## [v3.16.3](https://github.com/bensheldon/good_job/tree/v3.16.3) (2023-07-18)
|
4
52
|
|
5
53
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.16.2...v3.16.3)
|
data/README.md
CHANGED
@@ -59,8 +59,8 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
|
|
59
59
|
- [Timeouts](#timeouts)
|
60
60
|
- [Optimize queues, threads, and processes](#optimize-queues-threads-and-processes)
|
61
61
|
- [Database connections](#database-connections)
|
62
|
-
|
63
|
-
|
62
|
+
- [Production setup](#production-setup)
|
63
|
+
- [Queue performance with Queue Select Limit](#queue-performance-with-queue-select-limit)
|
64
64
|
- [Execute jobs async / in-process](#execute-jobs-async--in-process)
|
65
65
|
- [Migrate to GoodJob from a different ActiveJob backend](#migrate-to-goodjob-from-a-different-activejob-backend)
|
66
66
|
- [Monitor and preserve worked jobs](#monitor-and-preserve-worked-jobs)
|
@@ -475,7 +475,7 @@ GoodJob's concurrency control strategy for `perform_limit` is "optimistic retry
|
|
475
475
|
|
476
476
|
GoodJob can enqueue jobs on a recurring basis that can be used as a replacement for cron.
|
477
477
|
|
478
|
-
Cron-style jobs
|
478
|
+
Cron-style jobs can be performed by any GoodJob process (e.g., CLI or `:async` execution mode) that has `config.good_job.enable_cron` set to `true`. That is, one or more job executor processes can be configured to perform recurring jobs.
|
479
479
|
|
480
480
|
GoodJob's cron uses unique indexes to ensure that only a single job is enqueued at the given time interval. In order for this to work, GoodJob must preserve cron-created job records; these records will be automatically deleted like any other preserved record.
|
481
481
|
|
@@ -484,7 +484,7 @@ Cron-format is parsed by the [`fugit`](https://github.com/floraison/fugit) gem,
|
|
484
484
|
```ruby
|
485
485
|
# config/environments/application.rb or a specific environment e.g. production.rb
|
486
486
|
|
487
|
-
# Enable cron in this process
|
487
|
+
# Enable cron in this process, e.g., only run on the first Heroku worker process
|
488
488
|
config.good_job.enable_cron = ENV['DYNO'] == 'worker.1' # or `true` or via $GOOD_JOB_ENABLE_CRON
|
489
489
|
|
490
490
|
# Configure cron with a hash that has a unique key for each recurring job
|
@@ -954,24 +954,50 @@ Keep in mind, queue operations and management is an advanced discipline. This st
|
|
954
954
|
|
955
955
|
### Database connections
|
956
956
|
|
957
|
-
|
957
|
+
GoodJob job executor processes require the following database connections:
|
958
|
+
|
959
|
+
- 1 connection per execution pool thread. E.g., `--queues=mice:2;elephants:1` is 3 threads and thus 3 connections. Pool size defaults to `--max-threads`.
|
960
|
+
- 2 additional connections that GoodJob uses for utility functionality (e.g. LISTEN/NOTIFY, cron, etc.)
|
961
|
+
- 1 connection per subthread, if your application makes multithreaded database queries (e.g. `load_async`) within a job.
|
962
|
+
|
963
|
+
The executor process will not crash if the connections pool is exhausted, instead it will report an exception (eg. `ActiveRecord::ConnectionTimeoutError`).
|
964
|
+
|
965
|
+
When GoodJob runs in `:inline` mode (in Rails' test environment, by default), the default database pool configuration works.
|
966
|
+
|
967
|
+
```yml
|
968
|
+
# config/database.yml
|
969
|
+
|
970
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
971
|
+
```
|
972
|
+
|
973
|
+
When GoodJob runs in `:async` mode (in Rails's development environment, by default), the following database pool configuration works, where:
|
974
|
+
|
975
|
+
- `ENV.fetch("RAILS_MAX_THREADS", 5)` is the number of threads used by the web server
|
976
|
+
- `1` is the number of connections used by the job listener
|
977
|
+
- `2` is the number of connections used by the cron scheduler and executor
|
978
|
+
- `ENV.fetch("GOOD_JOB_MAX_THREADS", 5)` is the number of threads used to perform jobs
|
958
979
|
|
959
980
|
```yaml
|
960
981
|
# config/database.yml
|
961
|
-
|
982
|
+
|
983
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5).to_i + 1 + 2 + ENV.fetch("GOOD_JOB_MAX_THREADS", 5).to_i %>
|
962
984
|
```
|
963
985
|
|
964
|
-
|
986
|
+
When GoodJob runs in `:external` mode (in Rails' production environment, by default), the following database pool configurations work for web servers and worker processes, respectively.
|
965
987
|
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
988
|
+
```yaml
|
989
|
+
# config/database.yml
|
990
|
+
|
991
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %>
|
992
|
+
```
|
971
993
|
|
972
|
-
|
994
|
+
```yaml
|
995
|
+
# config/database.yml
|
996
|
+
|
997
|
+
pool: <%= 1 + 2 + ENV.fetch("GOOD_JOB_MAX_THREADS", 5).to_i %>
|
998
|
+
```
|
973
999
|
|
974
|
-
|
1000
|
+
### Production setup
|
975
1001
|
|
976
1002
|
When running GoodJob in a production environment, you should be mindful of:
|
977
1003
|
|
@@ -986,7 +1012,7 @@ The recommended way to monitor the queue in production is:
|
|
986
1012
|
- keep an eye on the number of jobs in the queue (abnormal high number of unscheduled jobs means the queue could be underperforming)
|
987
1013
|
- consider performance monitoring services which support the built-in Rails instrumentation (eg. Sentry, Skylight, etc.)
|
988
1014
|
|
989
|
-
|
1015
|
+
### Queue performance with Queue Select Limit
|
990
1016
|
|
991
1017
|
GoodJob’s advisory locking strategy uses a materialized CTE (Common Table Expression). This strategy can be non-performant when querying a very large queue of executable jobs (100,000+) because the database query must materialize all executable jobs before acquiring an advisory lock.
|
992
1018
|
|
@@ -8,7 +8,9 @@ import setupPopovers from "popovers";
|
|
8
8
|
import LivePoll from "live_poll";
|
9
9
|
|
10
10
|
import { Application } from "stimulus";
|
11
|
+
import ThemeController from "theme_controller";
|
11
12
|
window.Stimulus = Application.start();
|
13
|
+
Stimulus.register("theme", ThemeController)
|
12
14
|
|
13
15
|
documentReady(function() {
|
14
16
|
renderCharts();
|
@@ -0,0 +1,44 @@
|
|
1
|
+
// hello_controller.js
|
2
|
+
import { Controller } from "stimulus"
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = [ "dropdown", "button" ]
|
5
|
+
|
6
|
+
connect() {
|
7
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
8
|
+
const theme = localStorage.getItem('good_job-theme');
|
9
|
+
if (!["light", "dark"].includes(theme)) {
|
10
|
+
this.setTheme(this.autoTheme());
|
11
|
+
}
|
12
|
+
});
|
13
|
+
|
14
|
+
this.setTheme(this.getStoredTheme() || 'light');
|
15
|
+
}
|
16
|
+
|
17
|
+
change(event) {
|
18
|
+
const theme = event.params.value;
|
19
|
+
localStorage.setItem('good_job-theme', theme);
|
20
|
+
this.setTheme(theme);
|
21
|
+
}
|
22
|
+
|
23
|
+
setTheme(theme) {
|
24
|
+
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? this.autoTheme() : theme);
|
25
|
+
|
26
|
+
this.buttonTargets.forEach((button) => {
|
27
|
+
button.classList.remove('active');
|
28
|
+
if (button.dataset.themeValueParam === theme) {
|
29
|
+
button.classList.add('active');
|
30
|
+
}
|
31
|
+
});
|
32
|
+
|
33
|
+
const svg = this.buttonTargets.filter(b => b.matches(".active"))[0]?.querySelector('svg');
|
34
|
+
this.dropdownTarget.querySelector('svg').outerHTML = svg.outerHTML;
|
35
|
+
}
|
36
|
+
|
37
|
+
getStoredTheme() {
|
38
|
+
return localStorage.getItem('good_job-theme');
|
39
|
+
}
|
40
|
+
|
41
|
+
autoTheme() {
|
42
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
43
|
+
}
|
44
|
+
}
|