good_job 3.22.0 → 3.24.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 +57 -1
- data/README.md +107 -16
- data/app/helpers/good_job/application_helper.rb +3 -2
- data/app/models/good_job/base_execution.rb +10 -3
- data/app/models/good_job/batch.rb +1 -1
- data/app/models/good_job/batch_record.rb +1 -1
- data/app/views/good_job/shared/_filter.erb +2 -2
- data/app/views/good_job/shared/_navbar.erb +21 -3
- data/app/views/good_job/shared/icons/_globe.html.erb +3 -0
- data/config/locales/ko.yml +243 -0
- data/config/locales/pt-BR.yml +243 -0
- data/config/locales/ru.yml +74 -76
- data/lib/generators/good_job/templates/install/migrations/create_good_jobs.rb.erb +2 -0
- data/lib/generators/good_job/templates/update/migrations/11_create_index_good_job_jobs_for_candidate_lookup.rb.erb +19 -0
- data/lib/good_job/active_job_extensions/concurrency.rb +8 -0
- data/lib/good_job/adapter.rb +2 -2
- data/lib/good_job/cli.rb +5 -2
- data/lib/good_job/configuration.rb +18 -2
- data/lib/good_job/probe_server/healthcheck_middleware.rb +27 -0
- data/lib/good_job/probe_server/not_found_app.rb +11 -0
- data/lib/good_job/probe_server/simple_handler.rb +83 -0
- data/lib/good_job/probe_server/webrick_handler.rb +28 -0
- data/lib/good_job/probe_server.rb +21 -16
- data/lib/good_job/version.rb +1 -1
- data/lib/good_job.rb +6 -3
- metadata +25 -4
- data/lib/good_job/http_server.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b464ea5a307aa615b5800649e4ff4083276900fe42bfb32edfc9ed66c470914
|
4
|
+
data.tar.gz: 7ff522ebb69f55a222a089ddc7c2b1fc2e0835603bcf515a630b2b27a2e90b7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae2eb90d2b35711d3d4ade8ed678bba89e36fa32eb36b6bb291a4b99fbe0d60b4ea2a143521f9b20b6d386b745d690f8e6b99467b0ec1b05d9e44709f71a6b7f
|
7
|
+
data.tar.gz: a695f55188543d9ea6d53f1f25c4e3cfb311d4a4d7dddbed342b8034e5d09cf911f212e57fe4fba0ab64c0cc8ce0f9dcb2529756dc9c701403e5e6ee1b8113e7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,62 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v3.24.0](https://github.com/bensheldon/good_job/tree/v3.24.0) (2024-02-12)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.23.0...v3.24.0)
|
6
|
+
|
7
|
+
**Fixed bugs:**
|
8
|
+
|
9
|
+
- Fix batches so that retried-and-successful jobs leave the batch succeeded [\#1243](https://github.com/bensheldon/good_job/pull/1243) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
- Use the job class as the default concurrency key if none is provided [\#1145](https://github.com/bensheldon/good_job/pull/1145) ([Earlopain](https://github.com/Earlopain))
|
11
|
+
|
12
|
+
**Closed issues:**
|
13
|
+
|
14
|
+
- Batch callbacks not run when job fails, then succeeds [\#1239](https://github.com/bensheldon/good_job/issues/1239)
|
15
|
+
- Broken pipe @ io\_writev - \<STDERR\> \(Errno::EPIPE\) [\#1233](https://github.com/bensheldon/good_job/issues/1233)
|
16
|
+
- PG::UniqueViolation unique constraint "index\_good\_jobs\_on\_cron\_key\_and\_cron\_at\_cond" [\#1230](https://github.com/bensheldon/good_job/issues/1230)
|
17
|
+
- Default concurrency key [\#1110](https://github.com/bensheldon/good_job/issues/1110)
|
18
|
+
|
19
|
+
**Merged pull requests:**
|
20
|
+
|
21
|
+
- Use Ruby 3.3 for development; add Bootsnap; update to Rails 7.1.3 [\#1240](https://github.com/bensheldon/good_job/pull/1240) ([bensheldon](https://github.com/bensheldon))
|
22
|
+
- Tweak docs for new concurrency default [\#1229](https://github.com/bensheldon/good_job/pull/1229) ([Earlopain](https://github.com/Earlopain))
|
23
|
+
- Brazilian Portuguese locale [\#1226](https://github.com/bensheldon/good_job/pull/1226) ([hss-mateus](https://github.com/hss-mateus))
|
24
|
+
|
25
|
+
## [v3.23.0](https://github.com/bensheldon/good_job/tree/v3.23.0) (2024-01-23)
|
26
|
+
|
27
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.22.0...v3.23.0)
|
28
|
+
|
29
|
+
**Implemented enhancements:**
|
30
|
+
|
31
|
+
- Add environment label to navbar [\#1206](https://github.com/bensheldon/good_job/pull/1206) ([sparshalc](https://github.com/sparshalc))
|
32
|
+
- Make health probe server more general purpose [\#1079](https://github.com/bensheldon/good_job/pull/1079) ([jklina](https://github.com/jklina))
|
33
|
+
|
34
|
+
**Fixed bugs:**
|
35
|
+
|
36
|
+
- Use Rails executor instead of reloader when wrapping inline execution [\#1225](https://github.com/bensheldon/good_job/pull/1225) ([bensheldon](https://github.com/bensheldon))
|
37
|
+
- Add an index to better support `smaller_number_is_higher_priority` [\#1213](https://github.com/bensheldon/good_job/pull/1213) ([mkrfowler](https://github.com/mkrfowler))
|
38
|
+
- Fix discard job with nonexistent job class [\#1211](https://github.com/bensheldon/good_job/pull/1211) ([yenshirak](https://github.com/yenshirak))
|
39
|
+
- Fix: Interacting with input field should pause the live poll [\#1210](https://github.com/bensheldon/good_job/pull/1210) ([sparshalc](https://github.com/sparshalc))
|
40
|
+
|
41
|
+
**Closed issues:**
|
42
|
+
|
43
|
+
- can't write unknown attribute `active_job_id` [\#1216](https://github.com/bensheldon/good_job/issues/1216)
|
44
|
+
- Regression: use of Rails reloader causing mixed constants during seeding [\#1215](https://github.com/bensheldon/good_job/issues/1215)
|
45
|
+
- Production worker doesn't show any processes [\#1214](https://github.com/bensheldon/good_job/issues/1214)
|
46
|
+
- Clarify required async mode DB pool size [\#1209](https://github.com/bensheldon/good_job/issues/1209)
|
47
|
+
- Mac forking exception when using Spring [\#1115](https://github.com/bensheldon/good_job/issues/1115)
|
48
|
+
- Jobs should have labels [\#1095](https://github.com/bensheldon/good_job/issues/1095)
|
49
|
+
- Set up Dependabot grouped updates [\#1062](https://github.com/bensheldon/good_job/issues/1062)
|
50
|
+
- Fix documentation to always include space in "Active Job", "Active Record", etc. [\#1048](https://github.com/bensheldon/good_job/issues/1048)
|
51
|
+
|
52
|
+
**Merged pull requests:**
|
53
|
+
|
54
|
+
- Bump actions/cache from 3 to 4 [\#1223](https://github.com/bensheldon/good_job/pull/1223) ([dependabot[bot]](https://github.com/apps/dependabot))
|
55
|
+
- Update README, add poll\_interval defaults/recommendations [\#1220](https://github.com/bensheldon/good_job/pull/1220) ([andynu](https://github.com/andynu))
|
56
|
+
- Update Russian translation [\#1219](https://github.com/bensheldon/good_job/pull/1219) ([alec-c4](https://github.com/alec-c4))
|
57
|
+
- Add Korean translation \(ko\) [\#1212](https://github.com/bensheldon/good_job/pull/1212) ([hahwul](https://github.com/hahwul))
|
58
|
+
- Fix default poll interval in documentation [\#1208](https://github.com/bensheldon/good_job/pull/1208) ([yenshirak](https://github.com/yenshirak))
|
59
|
+
|
3
60
|
## [v3.22.0](https://github.com/bensheldon/good_job/tree/v3.22.0) (2024-01-03)
|
4
61
|
|
5
62
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.21.5...v3.22.0)
|
@@ -1603,7 +1660,6 @@
|
|
1603
1660
|
**Fixed bugs:**
|
1604
1661
|
|
1605
1662
|
- `ActionMailer::MailDeliveryJob` executing twice [\#329](https://github.com/bensheldon/good_job/issues/329)
|
1606
|
-
- Email job breaks dashboard [\#313](https://github.com/bensheldon/good_job/issues/313)
|
1607
1663
|
|
1608
1664
|
**Closed issues:**
|
1609
1665
|
|
data/README.md
CHANGED
@@ -177,18 +177,19 @@ Usage:
|
|
177
177
|
good_job start
|
178
178
|
|
179
179
|
Options:
|
180
|
-
[--queues=QUEUE_LIST]
|
181
|
-
[--max-threads=COUNT]
|
182
|
-
[--poll-interval=SECONDS]
|
183
|
-
[--max-cache=COUNT]
|
184
|
-
[--shutdown-timeout=SECONDS]
|
185
|
-
[--enable-cron]
|
186
|
-
[--enable-listen-notify]
|
187
|
-
[--idle-timeout=SECONDS]
|
188
|
-
[--daemonize]
|
189
|
-
[--pidfile=PIDFILE]
|
190
|
-
[--probe-port=PORT]
|
191
|
-
[--
|
180
|
+
[--queues=QUEUE_LIST] # Queues or pools to work from. (env var: GOOD_JOB_QUEUES, default: *)
|
181
|
+
[--max-threads=COUNT] # Default number of threads per pool to use for working jobs. (env var: GOOD_JOB_MAX_THREADS, default: 5)
|
182
|
+
[--poll-interval=SECONDS] # Interval between polls for available jobs in seconds (env var: GOOD_JOB_POLL_INTERVAL, default: 10)
|
183
|
+
[--max-cache=COUNT] # Maximum number of scheduled jobs to cache in memory (env var: GOOD_JOB_MAX_CACHE, default: 10000)
|
184
|
+
[--shutdown-timeout=SECONDS] # Number of seconds to wait for jobs to finish when shutting down before stopping the thread. (env var: GOOD_JOB_SHUTDOWN_TIMEOUT, default: -1 (forever))
|
185
|
+
[--enable-cron] # Whether to run cron process (default: false)
|
186
|
+
[--enable-listen-notify] # Whether to enqueue and read jobs with Postgres LISTEN/NOTIFY (default: true)
|
187
|
+
[--idle-timeout=SECONDS] # Exit process when no jobs have been performed for this many seconds (env var: GOOD_JOB_IDLE_TIMEOUT, default: nil)
|
188
|
+
[--daemonize] # Run as a background daemon (default: false)
|
189
|
+
[--pidfile=PIDFILE] # Path to write daemonized Process ID (env var: GOOD_JOB_PIDFILE, default: tmp/pids/good_job.pid)
|
190
|
+
[--probe-port=PORT] # Port for http health check (env var: GOOD_JOB_PROBE_PORT, default: nil)
|
191
|
+
[--probe-handler=PROBE_HANDLER] # Use 'webrick' to use WEBrick to handle probe server requests which is Rack compliant, otherwise default server that is not Rack compliant is used.
|
192
|
+
[--queue-select-limit=COUNT] # The number of queued jobs to select when polling for a job to run. (env var: GOOD_JOB_QUEUE_SELECT_LIMIT, default: nil)"
|
192
193
|
|
193
194
|
Executes queued jobs.
|
194
195
|
|
@@ -280,6 +281,10 @@ Available configuration options are:
|
|
280
281
|
- `queues` (string) sets queues or pools to execute jobs. You can also set this with the environment variable `GOOD_JOB_QUEUES`.
|
281
282
|
- `max_threads` (integer) sets the default number of threads per pool to use for working jobs. You can also set this with the environment variable `GOOD_JOB_MAX_THREADS`.
|
282
283
|
- `poll_interval` (integer) sets the number of seconds between polls for jobs when `execution_mode` is set to `:async`. You can also set this with the environment variable `GOOD_JOB_POLL_INTERVAL`. A poll interval of `-1` disables polling completely.
|
284
|
+
- production default: 10 seconds (in case of a LISTEN/NOTIFY blip)
|
285
|
+
- development default: -1, disabled (because the application is likely being restarted often and won't be running unobserved). You can enable it by setting a `poll_interval`.
|
286
|
+
- LISTEN/NOTIFY is enabled in both production and development, so polling is not strictly necessary.
|
287
|
+
- If LISTEN/NOTIFY is disabled, you should configure polling for future-scheduled jobs. GoodJob will cache in memory the scheduled time and check for executable jobs at that time. If the cache is exceeded (10k scheduled jobs by default) that's another reason to poll just in case.
|
283
288
|
- `max_cache` (integer) sets the maximum number of scheduled jobs that will be stored in memory to reduce execution latency when also polling for scheduled jobs. Caching 10,000 scheduled jobs uses approximately 20MB of memory. You can also set this with the environment variable `GOOD_JOB_MAX_CACHE`.
|
284
289
|
- `shutdown_timeout` (integer) number of seconds to wait for jobs to finish when shutting down before stopping the thread. Defaults to forever: `-1`. You can also set this with the environment variable `GOOD_JOB_SHUTDOWN_TIMEOUT`.
|
285
290
|
- `enable_cron` (boolean) whether to run cron process. Defaults to `false`. You can also set this with the environment variable `GOOD_JOB_ENABLE_CRON`.
|
@@ -300,6 +305,18 @@ Available configuration options are:
|
|
300
305
|
config.good_job.on_thread_error = -> (exception) { Rails.error.report(exception) }
|
301
306
|
```
|
302
307
|
|
308
|
+
- `probe_server_app` (Rack application) allows you to specify a Rack application to be used for the probe server. Defaults to `nil` which uses the default probe server. Example:
|
309
|
+
|
310
|
+
```ruby
|
311
|
+
config.good_job.probe_app = -> (env) { [200, {}, ["OK"]] }
|
312
|
+
```
|
313
|
+
|
314
|
+
- `probe_handler` (string) allows you to use WEBrick, a fully Rack compliant webserver instead of the simple default server. **Note:** You'll need to ensure WEBrick is in your load path as GoodJob doesn't have WEBrick as a dependency. Example:
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
config.good_job.probe_handler = 'webrick'
|
318
|
+
```
|
319
|
+
|
303
320
|
By default, GoodJob configures the following execution modes per environment:
|
304
321
|
|
305
322
|
```ruby
|
@@ -494,12 +511,25 @@ class MyJob < ApplicationJob
|
|
494
511
|
|
495
512
|
# A unique key to be globally locked against.
|
496
513
|
# Can be String or Lambda/Proc that is invoked in the context of the job.
|
514
|
+
#
|
515
|
+
# If a key is not provided GoodJob will use the job class name.
|
516
|
+
#
|
517
|
+
# To disable concurrency control, for example in a subclass, set the
|
518
|
+
# key explicitly to nil (e.g. `key: nil` or `key: -> { nil }`)
|
519
|
+
#
|
520
|
+
# If you provide a custom concurrency key (for example, if concurrency is supposed
|
521
|
+
# to be controlled by the first job argument) make sure that it is sufficiently unique across
|
522
|
+
# jobs and queues by adding the job class or queue to the key yourself, if needed.
|
523
|
+
#
|
524
|
+
# Note: When using a model instance as part of your custom concurrency key, make sure
|
525
|
+
# to explicitly use its `id` or `to_global_id` because otherwise it will not stringify as expected.
|
526
|
+
#
|
497
527
|
# Note: Arguments passed to #perform_later can be accessed through Active Job's `arguments` method
|
498
528
|
# which is an array containing positional arguments and, optionally, a kwarg hash.
|
499
|
-
key: -> { "
|
529
|
+
key: -> { "#{self.class.name}-#{queue_name}-#{arguments.first}-#{arguments.last[:version]}" } # MyJob.perform_later("Alice", version: 'v2') => "MyJob-default-Alice-v2"
|
500
530
|
)
|
501
531
|
|
502
|
-
def perform(first_name)
|
532
|
+
def perform(first_name, version:)
|
503
533
|
# do work
|
504
534
|
end
|
505
535
|
end
|
@@ -508,8 +538,8 @@ end
|
|
508
538
|
When testing, the resulting concurrency key value can be inspected:
|
509
539
|
|
510
540
|
```ruby
|
511
|
-
job = MyJob.perform_later("Alice")
|
512
|
-
job.good_job_concurrency_key #=> "MyJob-Alice"
|
541
|
+
job = MyJob.perform_later("Alice", version: 'v1')
|
542
|
+
job.good_job_concurrency_key #=> "MyJob-default-Alice-v1"
|
513
543
|
```
|
514
544
|
|
515
545
|
#### How concurrency controls work
|
@@ -1317,6 +1347,8 @@ A workaround to this limitation is to make a direct database connection availabl
|
|
1317
1347
|
|
1318
1348
|
### CLI HTTP health check probes
|
1319
1349
|
|
1350
|
+
#### Default configuration
|
1351
|
+
|
1320
1352
|
GoodJob's CLI offers an http health check probe to better manage process lifecycle in containerized environments like Kubernetes:
|
1321
1353
|
|
1322
1354
|
```bash
|
@@ -1370,6 +1402,65 @@ spec:
|
|
1370
1402
|
periodSeconds: 10
|
1371
1403
|
```
|
1372
1404
|
|
1405
|
+
#### Custom configuration
|
1406
|
+
|
1407
|
+
The CLI health check probe server can be customized to serve additional information. Two things to note when customizing the probe server:
|
1408
|
+
|
1409
|
+
- By default, the probe server uses a homespun single thread, blocking server so your custom app should be very simple and lightly used and could affect job performance.
|
1410
|
+
- The default probe server is not fully Rack compliant. Rack specifies various mandatory fields and some Rack apps assume those fields exist. If you do need to use a Rack app that depends on being fully Rack compliant, you can configure GoodJob to [use WEBrick as the server](#using-webrick)
|
1411
|
+
|
1412
|
+
To customize the probe server, set `config.good_job.probe_app` to a Rack app or a Rack builder:
|
1413
|
+
|
1414
|
+
```ruby
|
1415
|
+
# config/initializers/good_job.rb OR config/application.rb OR config/environments/{RAILS_ENV}.rb
|
1416
|
+
|
1417
|
+
Rails.application.configure do
|
1418
|
+
config.good_job.probe_app = Rack::Builder.new do
|
1419
|
+
# Add your custom middleware
|
1420
|
+
use Custom::AuthorizationMiddleware
|
1421
|
+
use Custom::PrometheusExporter
|
1422
|
+
|
1423
|
+
# This is the default middleware
|
1424
|
+
use GoodJob::ProbeServer::HealthcheckMiddleware
|
1425
|
+
run GoodJob::ProbeServer::NotFoundApp # will return 404 for all other requests
|
1426
|
+
end
|
1427
|
+
end
|
1428
|
+
```
|
1429
|
+
|
1430
|
+
##### Using WEBrick
|
1431
|
+
|
1432
|
+
If your custom app requires a fully Rack compliant server, you can configure GoodJob to use WEBrick as the server:
|
1433
|
+
|
1434
|
+
```ruby
|
1435
|
+
# config/initializers/good_job.rb OR config/application.rb OR config/environments/{RAILS_ENV}.rb
|
1436
|
+
|
1437
|
+
Rails.application.configure do
|
1438
|
+
config.good_job.probe_handler = :webrick
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
```
|
1442
|
+
|
1443
|
+
You can also enable WEBrick through the command line:
|
1444
|
+
|
1445
|
+
```bash
|
1446
|
+
good_job start --probe-handler=webrick
|
1447
|
+
```
|
1448
|
+
|
1449
|
+
or via an environment variable:
|
1450
|
+
|
1451
|
+
```bash
|
1452
|
+
GOOD_JOB_PROBE_HANDLER=webrick good_job start
|
1453
|
+
```
|
1454
|
+
|
1455
|
+
Note that GoodJob doesn't include WEBrick as a dependency, so you'll need to add it to your Gemfile:
|
1456
|
+
|
1457
|
+
```ruby
|
1458
|
+
# Gemfile
|
1459
|
+
gem 'webrick'
|
1460
|
+
```
|
1461
|
+
|
1462
|
+
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.
|
1463
|
+
|
1373
1464
|
## Contribute
|
1374
1465
|
|
1375
1466
|
<!-- Please keep this section in sync with CONTRIBUTING.md -->
|
@@ -53,10 +53,11 @@ module GoodJob
|
|
53
53
|
content_tag :span, icon, **options
|
54
54
|
end
|
55
55
|
|
56
|
-
def render_icon(name)
|
56
|
+
def render_icon(name, **options)
|
57
57
|
# workaround to render svg icons without all of the log messages
|
58
58
|
partial = lookup_context.find_template("good_job/shared/icons/#{name}", [], true)
|
59
|
-
|
59
|
+
options[:class] = Array(options[:class]).join(" ")
|
60
|
+
partial.render(self, { class: options[:class] })
|
60
61
|
end
|
61
62
|
|
62
63
|
def translate_hash(key, **options)
|
@@ -77,6 +77,13 @@ module GoodJob
|
|
77
77
|
migration_pending_warning!
|
78
78
|
false
|
79
79
|
end
|
80
|
+
|
81
|
+
def candidate_lookup_index_migrated?
|
82
|
+
return true if connection.index_name_exists?(:good_jobs, :index_good_job_jobs_for_candidate_lookup)
|
83
|
+
|
84
|
+
migration_pending_warning!
|
85
|
+
false
|
86
|
+
end
|
80
87
|
end
|
81
88
|
|
82
89
|
# The ActiveJob job class, as a string
|
@@ -92,14 +99,14 @@ module GoodJob
|
|
92
99
|
# Build an ActiveJob instance and deserialize the arguments, using `#active_job_data`.
|
93
100
|
#
|
94
101
|
# @param ignore_deserialization_errors [Boolean]
|
95
|
-
# Whether to ignore ActiveJob::DeserializationError when deserializing the arguments.
|
102
|
+
# Whether to ignore ActiveJob::DeserializationError and NameError when deserializing the arguments.
|
96
103
|
# This is most useful if you aren't planning to use the arguments directly.
|
97
104
|
def active_job(ignore_deserialization_errors: false)
|
98
105
|
ActiveJob::Base.deserialize(active_job_data).tap do |aj|
|
99
106
|
aj.send(:deserialize_arguments_if_needed)
|
100
|
-
rescue ActiveJob::DeserializationError
|
101
|
-
raise unless ignore_deserialization_errors
|
102
107
|
end
|
108
|
+
rescue ActiveJob::DeserializationError, NameError
|
109
|
+
raise unless ignore_deserialization_errors
|
103
110
|
end
|
104
111
|
|
105
112
|
private
|
@@ -101,7 +101,7 @@ module GoodJob
|
|
101
101
|
|
102
102
|
active_jobs = add(active_jobs, &block)
|
103
103
|
|
104
|
-
Rails.application.
|
104
|
+
Rails.application.executor.wrap do
|
105
105
|
record.with_advisory_lock(function: "pg_advisory_lock") do
|
106
106
|
record.update!(enqueued_at: Time.current)
|
107
107
|
|
@@ -46,7 +46,7 @@ module GoodJob
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def _continue_discard_or_finish(execution = nil, lock: true)
|
49
|
-
execution_discarded = execution && execution.error.present? && execution.retried_good_job_id.nil?
|
49
|
+
execution_discarded = execution && execution.error.present? && execution.finished_at && execution.retried_good_job_id.nil?
|
50
50
|
take_advisory_lock(lock) do
|
51
51
|
Batch.within_thread(batch_id: nil, batch_callback_id: id) do
|
52
52
|
reload
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div
|
1
|
+
<div id="filter">
|
2
2
|
<div class="">
|
3
3
|
<div class="border-bottom mb-3">
|
4
4
|
<h2 class="pt-3 pb-2"><%= title %></h2>
|
@@ -47,7 +47,7 @@
|
|
47
47
|
</div>
|
48
48
|
<% end %>
|
49
49
|
|
50
|
-
<ul class="nav nav-tabs my-3">
|
50
|
+
<ul data-live-poll-region="filter-tabs" class="nav nav-tabs my-3">
|
51
51
|
<li class="nav-item">
|
52
52
|
<%= link_to t(".all"), filter.to_params(state: nil), class: "nav-link #{"active" unless params[:state].present?}" %>
|
53
53
|
</li>
|
@@ -1,7 +1,15 @@
|
|
1
1
|
<nav class="navbar navbar-expand-lg border-bottom bg-body sticky-top">
|
2
2
|
<div class="container-fluid">
|
3
3
|
<%= link_to t(".name"), root_path, class: "navbar-brand mb-0 h1" %>
|
4
|
-
|
4
|
+
|
5
|
+
<div class="d-lg-none d-flex flex-fill justify-content-end me-2">
|
6
|
+
<span class="navbar-text">
|
7
|
+
<%= render_icon "globe", class: "align-text-bottom" %>
|
8
|
+
<small><%= Rails.env.capitalize %></small>
|
9
|
+
</span>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<button class="navbar-toggler position-relative" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
5
13
|
<span class="navbar-toggler-icon"></span>
|
6
14
|
</button>
|
7
15
|
|
@@ -37,9 +45,19 @@
|
|
37
45
|
</li>
|
38
46
|
</ul>
|
39
47
|
|
40
|
-
<hr class="d-lg-none text-secondary">
|
41
|
-
|
42
48
|
<ul class="navbar-nav">
|
49
|
+
<li class="nav-item d-none d-lg-flex align-items-center">
|
50
|
+
<span class="navbar-text">
|
51
|
+
<%= render_icon "globe", class: "align-text-bottom" %>
|
52
|
+
<small><%= Rails.env.capitalize %></small>
|
53
|
+
</span>
|
54
|
+
</li>
|
55
|
+
|
56
|
+
<li class="nav-item py-2 py-lg-1 col-12 col-lg-auto">
|
57
|
+
<div class="vr d-none d-lg-flex h-100 mx-lg-2 text-secondary"></div>
|
58
|
+
<hr class="d-lg-none my-2 text-secondary">
|
59
|
+
</li>
|
60
|
+
|
43
61
|
<li class="nav-item d-flex flex-column justify-content-center">
|
44
62
|
<div class="form-check form-switch m-0">
|
45
63
|
<%= check_box_tag "live_poll", params.fetch("poll", 30), params[:poll].present?, role: "switch", class: "form-check-input" %>
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-globe <%= local_assigns[:class] %>" viewBox="0 0 16 16">
|
2
|
+
<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m7.5-6.923c-.67.204-1.335.82-1.887 1.855A8 8 0 0 0 5.145 4H7.5zM4.09 4a9.3 9.3 0 0 1 .64-1.539 7 7 0 0 1 .597-.933A7.03 7.03 0 0 0 2.255 4zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a7 7 0 0 0-.656 2.5zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5zM8.5 5v2.5h2.99a12.5 12.5 0 0 0-.337-2.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5zM5.145 12q.208.58.468 1.068c.552 1.035 1.218 1.65 1.887 1.855V12zm.182 2.472a7 7 0 0 1-.597-.933A9.3 9.3 0 0 1 4.09 12H2.255a7 7 0 0 0 3.072 2.472M3.82 11a13.7 13.7 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5zm6.853 3.472A7 7 0 0 0 13.745 12H11.91a9.3 9.3 0 0 1-.64 1.539 7 7 0 0 1-.597.933M8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855q.26-.487.468-1.068zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.7 13.7 0 0 1-.312 2.5m2.802-3.5a7 7 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7 7 0 0 0-3.072-2.472c.218.284.418.598.597.933M10.855 4a8 8 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4z" />
|
3
|
+
</svg>
|
@@ -0,0 +1,243 @@
|
|
1
|
+
---
|
2
|
+
ko:
|
3
|
+
good_job:
|
4
|
+
actions:
|
5
|
+
destroy: 삭제하기
|
6
|
+
discard: 폐기하기
|
7
|
+
force_discard: 강제 폐기
|
8
|
+
inspect: 검사하기
|
9
|
+
reschedule: 재예약하기
|
10
|
+
retry: 다시 시도하기
|
11
|
+
batches:
|
12
|
+
index:
|
13
|
+
older_batches: 더 오래된 배치
|
14
|
+
pending_migrations: GoodJob에 보류 중인 데이터베이스 마이그레이션 작업이 있습니다.
|
15
|
+
title: 배치
|
16
|
+
jobs:
|
17
|
+
actions:
|
18
|
+
confirm_destroy: 이 작업을 삭제하시겠습니까?
|
19
|
+
confirm_discard: 이 작업을 폐기하시겠습니까?
|
20
|
+
confirm_reschedule: 이 작업을 다시 예약하시겠습니까?
|
21
|
+
confirm_retry: 이 작업을 다시 시도하시겠습니까?
|
22
|
+
destroy: 작업 삭제
|
23
|
+
discard: 작업 폐기
|
24
|
+
reschedule: 작업 재예약
|
25
|
+
retry: 작업 다시 시도
|
26
|
+
title: 작업 액션
|
27
|
+
no_jobs_found: 작업이 없습니다.
|
28
|
+
show:
|
29
|
+
attributes: 속성
|
30
|
+
batched_jobs: 배치된 작업
|
31
|
+
callback_jobs: 콜백 작업
|
32
|
+
table:
|
33
|
+
no_batches_found: 배치를 찾을 수 없습니다.
|
34
|
+
cron_entries:
|
35
|
+
actions:
|
36
|
+
confirm_disable: 이 cron 엔트리를 비활성화하시겠습니까?
|
37
|
+
confirm_enable: 이 cron 엔트리를 활성화하시겠습니까?
|
38
|
+
confirm_enqueue: 이 cron 엔트리를 큐에 넣으시겠습니까?
|
39
|
+
disable: cron 엔트리 비활성화
|
40
|
+
enable: cron 엔트리 활성화
|
41
|
+
enqueue: cron 엔트리 즉시 큐에 넣기
|
42
|
+
disable:
|
43
|
+
notice: cron 엔트리가 비활성화되었습니다.
|
44
|
+
enable:
|
45
|
+
notice: cron 엔트리가 활성화되었습니다.
|
46
|
+
enqueue:
|
47
|
+
notice: cron 엔트리가 큐에 넣어졌습니다.
|
48
|
+
index:
|
49
|
+
no_cron_schedules_found: cron 스케줄을 찾을 수 없습니다.
|
50
|
+
title: cron 스케줄
|
51
|
+
pending_migrations: 보류 중인 GoodJob 데이터베이스 마이그레이션이 필요합니다.
|
52
|
+
show:
|
53
|
+
cron_entry_key: cron 엔트리 키
|
54
|
+
datetime:
|
55
|
+
distance_in_words:
|
56
|
+
about_x_hours:
|
57
|
+
one: 약 1시간
|
58
|
+
other: 약 %{count}시간
|
59
|
+
about_x_months:
|
60
|
+
one: 약 1개월
|
61
|
+
other: 약 %{count}개월
|
62
|
+
about_x_years:
|
63
|
+
one: 약 1년
|
64
|
+
other: 약 %{count}년
|
65
|
+
almost_x_years:
|
66
|
+
one: 거의 1년
|
67
|
+
other: 거의 %{count}년
|
68
|
+
half_a_minute: 약 반 분
|
69
|
+
less_than_x_minutes:
|
70
|
+
one: 1분 미만
|
71
|
+
other: "%{count}분 미만"
|
72
|
+
less_than_x_seconds:
|
73
|
+
one: 1초 미만
|
74
|
+
other: "%{count}초 미만"
|
75
|
+
over_x_years:
|
76
|
+
one: 1년 이상
|
77
|
+
other: "%{count}년 이상"
|
78
|
+
x_days:
|
79
|
+
one: 1일
|
80
|
+
other: "%{count}일"
|
81
|
+
x_minutes:
|
82
|
+
one: 1분
|
83
|
+
other: "%{count}분"
|
84
|
+
x_months:
|
85
|
+
one: 1개월
|
86
|
+
other: "%{count}개월"
|
87
|
+
x_seconds:
|
88
|
+
one: 1초
|
89
|
+
other: "%{count}초"
|
90
|
+
x_years:
|
91
|
+
one: 1년
|
92
|
+
other: "%{count}년"
|
93
|
+
duration:
|
94
|
+
hours: "%{hour}시간 %{min}분"
|
95
|
+
less_than_10_seconds: "%{sec}초 미만"
|
96
|
+
milliseconds: "%{ms}밀리초"
|
97
|
+
minutes: "%{min}분 %{sec}초"
|
98
|
+
seconds: "%{sec}초"
|
99
|
+
error_event:
|
100
|
+
discarded: 폐기됨
|
101
|
+
handled: 처리됨
|
102
|
+
interrupted: 중단됨
|
103
|
+
retried: 다시 시도됨
|
104
|
+
retry_stopped: 다시 시도 중지됨
|
105
|
+
unhandled: 처리되지 않음
|
106
|
+
helpers:
|
107
|
+
relative_time:
|
108
|
+
future: "%{time} 후"
|
109
|
+
past: "%{time} 전"
|
110
|
+
jobs:
|
111
|
+
actions:
|
112
|
+
confirm_destroy: 해당 작업을 삭제하시겠습니까?
|
113
|
+
confirm_discard: 해당 작업을 폐기하시겠습니까?
|
114
|
+
confirm_force_discard: '이 작업을 강제로 폐기하시겠습니까? 작업은 폐기로 표시되지만, 실행 중인 작업은 중지되지 않습니다. 그러나 실패한 경우 재시도되지 않습니다.
|
115
|
+
|
116
|
+
'
|
117
|
+
confirm_reschedule: 해당 작업을 재예약하시겠습니까?
|
118
|
+
confirm_retry: 해당 작업을 다시 시도하시겠습니까?
|
119
|
+
destroy: 작업 삭제
|
120
|
+
discard: 작업 폐기
|
121
|
+
force_discard: 작업 강제 폐기
|
122
|
+
reschedule: 작업 재예약
|
123
|
+
retry: 작업 다시 시도
|
124
|
+
destroy:
|
125
|
+
notice: 작업이 삭제되었습니다.
|
126
|
+
discard:
|
127
|
+
notice: 작업이 폐기되었습니다.
|
128
|
+
executions:
|
129
|
+
in_queue: 대기 중
|
130
|
+
runtime: 실행 시간
|
131
|
+
title: 실행
|
132
|
+
force_discard:
|
133
|
+
notice: 작업이 강제로 폐기되었습니다. 계속해서 실행되지만 실패한 경우 재시도되지 않습니다.
|
134
|
+
index:
|
135
|
+
job_pagination: 작업 페이지네이션
|
136
|
+
older_jobs: 오래된 작업
|
137
|
+
reschedule:
|
138
|
+
notice: 작업이 재예약되었습니다.
|
139
|
+
retry:
|
140
|
+
notice: 작업이 다시 시도되었습니다.
|
141
|
+
show:
|
142
|
+
jobs: 작업
|
143
|
+
table:
|
144
|
+
actions:
|
145
|
+
apply_to_all:
|
146
|
+
one: 모든 1개의 작업에 적용
|
147
|
+
other: 모든 %{count}개의 작업에 적용
|
148
|
+
confirm_destroy_all: 선택한 작업을 모두 삭제해도 괜찮습니까?
|
149
|
+
confirm_discard_all: 선택한 작업을 모두 폐기해도 괜찮습니까?
|
150
|
+
confirm_reschedule_all: 선택한 작업을 모두 재예약해도 괜찮습니까?
|
151
|
+
confirm_retry_all: 선택한 작업을 모두 다시 시도해도 괜찮습니까?
|
152
|
+
destroy_all: 모두 삭제
|
153
|
+
discard_all: 모두 폐기
|
154
|
+
reschedule_all: 모두 재예약
|
155
|
+
retry_all: 모두 다시 시도
|
156
|
+
title: 액션
|
157
|
+
no_jobs_found: 작업을 찾을 수 없습니다.
|
158
|
+
toggle_actions: 액션 전환
|
159
|
+
toggle_all_jobs: 모든 작업 전환
|
160
|
+
models:
|
161
|
+
batch:
|
162
|
+
created: 생성됨
|
163
|
+
created_at: 생성 일시
|
164
|
+
discarded: 폐기됨
|
165
|
+
discarded_at: 폐기 일시
|
166
|
+
enqueued: 큐에 추가됨
|
167
|
+
enqueued_at: 큐에 추가된 일시
|
168
|
+
finished: 완료됨
|
169
|
+
finished_at: 완료 일시
|
170
|
+
jobs: 작업
|
171
|
+
name: 이름
|
172
|
+
cron:
|
173
|
+
class: 클래스
|
174
|
+
last_run: 마지막 실행 일시
|
175
|
+
next_scheduled: 다음 예정 일시
|
176
|
+
schedule: 스케줄
|
177
|
+
job:
|
178
|
+
arguments: 인수
|
179
|
+
attempts: 시도 횟수
|
180
|
+
priority: 우선순위
|
181
|
+
queue: 큐
|
182
|
+
number:
|
183
|
+
format:
|
184
|
+
delimiter: ","
|
185
|
+
separator: "."
|
186
|
+
human:
|
187
|
+
decimal_units:
|
188
|
+
delimiter: ","
|
189
|
+
format: "%n%u"
|
190
|
+
precision: 3
|
191
|
+
separator: "."
|
192
|
+
units:
|
193
|
+
billion: B
|
194
|
+
million: M
|
195
|
+
quadrillion: Q
|
196
|
+
thousand: K
|
197
|
+
trillion: T
|
198
|
+
unit: ''
|
199
|
+
processes:
|
200
|
+
index:
|
201
|
+
cron_enabled: Cron이 활성화되어 있음
|
202
|
+
no_good_job_processes_found: GoodJob의 프로세스를 찾을 수 없습니다.
|
203
|
+
process: 프로세스
|
204
|
+
schedulers: 스케줄러
|
205
|
+
started: 시작 일시
|
206
|
+
title: 프로세스
|
207
|
+
updated: 업데이트됨
|
208
|
+
shared:
|
209
|
+
boolean:
|
210
|
+
'false': 아니요
|
211
|
+
'true': 예
|
212
|
+
error: 오류
|
213
|
+
filter:
|
214
|
+
all: 모두
|
215
|
+
all_jobs: 모든 작업
|
216
|
+
all_queues: 모든 큐
|
217
|
+
clear: 지우기
|
218
|
+
job_name: 작업 이름
|
219
|
+
placeholder: 클래스 이름, 작업 ID, 작업 매개변수, 오류 텍스트로 검색
|
220
|
+
queue_name: 큐 이름
|
221
|
+
search: 검색
|
222
|
+
navbar:
|
223
|
+
batches: 배치
|
224
|
+
cron_schedules: Cron
|
225
|
+
jobs: 작업
|
226
|
+
live_poll: 실시간 업데이트
|
227
|
+
name: "GoodJob 👍"
|
228
|
+
processes: 프로세스
|
229
|
+
theme:
|
230
|
+
auto: 자동
|
231
|
+
dark: 어두운
|
232
|
+
light: 밝은
|
233
|
+
theme: 테마
|
234
|
+
secondary_navbar:
|
235
|
+
inspiration: 기억하세요, 당신도 좋은 일을 하고 있습니다!
|
236
|
+
last_updated: 최종 업데이트
|
237
|
+
status:
|
238
|
+
discarded: 폐기됨
|
239
|
+
queued: 대기 중
|
240
|
+
retried: 다시 시도됨
|
241
|
+
running: 실행 중
|
242
|
+
scheduled: 예정됨
|
243
|
+
succeeded: 성공함
|