good_job 1.0.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +79 -2
- data/README.md +230 -56
- data/lib/active_job/queue_adapters/good_job_adapter.rb +3 -12
- data/lib/generators/good_job/install_generator.rb +24 -0
- data/lib/generators/good_job/templates/migration.rb.erb +20 -0
- data/lib/good_job.rb +6 -2
- data/lib/good_job/adapter.rb +30 -16
- data/lib/good_job/cli.rb +18 -48
- data/lib/good_job/configuration.rb +55 -0
- data/lib/good_job/job.rb +43 -25
- data/lib/good_job/log_subscriber.rb +110 -0
- data/lib/good_job/multi_scheduler.rb +25 -0
- data/lib/good_job/performer.rb +4 -1
- data/lib/good_job/railtie.rb +1 -0
- data/lib/good_job/scheduler.rb +82 -15
- data/lib/good_job/version.rb +1 -1
- metadata +38 -6
- data/lib/good_job/logging.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4117e28d2a899ebb8b66a17fa79ff8495b36521d92f9146059c7b78406a361b6
|
4
|
+
data.tar.gz: 535dd8b9204cc76ee6749224217e5d33e23adc2414e8ca7c420d4deb35451efd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f8bf7bf0f21604eb08b814d032b4a964f220b6d6384b368de7263672ece002f8fd01e5e2d77b0c6ed93e31ac03f235a2c40b8ad3f532de3fb3c755cd629ad24
|
7
|
+
data.tar.gz: 6006611999250e6b7708f381302379f1a07ba3522151630b708388436c9264ea2e2b4277c5753027171e82e7dd8a82b6f272386ad39170a192b94d0b36e45111
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,80 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## [v1.
|
3
|
+
## [v1.1.2](https://github.com/bensheldon/good_job/tree/v1.1.2) (2020-08-13)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.1.1...v1.1.2)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Allow the omission of queue names within a scheduler [\#73](https://github.com/bensheldon/good_job/issues/73)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Allow named queues to be excluded with a minus [\#77](https://github.com/bensheldon/good_job/pull/77) ([bensheldon](https://github.com/bensheldon))
|
14
|
+
|
15
|
+
## [v1.1.1](https://github.com/bensheldon/good_job/tree/v1.1.1) (2020-08-12)
|
16
|
+
|
17
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.1.0...v1.1.1)
|
18
|
+
|
19
|
+
**Implemented enhancements:**
|
20
|
+
|
21
|
+
- Allow multiple schedulers within the same process. e.g. `queues=mice:2,elephants:4` [\#45](https://github.com/bensheldon/good_job/issues/45)
|
22
|
+
|
23
|
+
**Merged pull requests:**
|
24
|
+
|
25
|
+
- Allow instantiation of multiple schedulers via --queues [\#76](https://github.com/bensheldon/good_job/pull/76) ([bensheldon](https://github.com/bensheldon))
|
26
|
+
- Extract options parsing to Configuration object [\#74](https://github.com/bensheldon/good_job/pull/74) ([bensheldon](https://github.com/bensheldon))
|
27
|
+
|
28
|
+
## [v1.1.0](https://github.com/bensheldon/good_job/tree/v1.1.0) (2020-08-10)
|
29
|
+
|
30
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.0.3...v1.1.0)
|
31
|
+
|
32
|
+
**Closed issues:**
|
33
|
+
|
34
|
+
- Document reliability guarantees [\#59](https://github.com/bensheldon/good_job/issues/59)
|
35
|
+
- Document how to hook in exception monitor \(Sentry, Rollbar, etc\) [\#47](https://github.com/bensheldon/good_job/issues/47)
|
36
|
+
- Allow an Async mode [\#27](https://github.com/bensheldon/good_job/issues/27)
|
37
|
+
|
38
|
+
**Merged pull requests:**
|
39
|
+
|
40
|
+
- Add a callable hook on thread errors [\#71](https://github.com/bensheldon/good_job/pull/71) ([bensheldon](https://github.com/bensheldon))
|
41
|
+
- Clarify reliability guarantees [\#70](https://github.com/bensheldon/good_job/pull/70) ([bensheldon](https://github.com/bensheldon))
|
42
|
+
- Clean up Readme formatting; re-arrange tests for clarity and values [\#69](https://github.com/bensheldon/good_job/pull/69) ([bensheldon](https://github.com/bensheldon))
|
43
|
+
- Create an Async execution mode [\#68](https://github.com/bensheldon/good_job/pull/68) ([bensheldon](https://github.com/bensheldon))
|
44
|
+
- Move all stdout to LogSubscriber [\#67](https://github.com/bensheldon/good_job/pull/67) ([bensheldon](https://github.com/bensheldon))
|
45
|
+
- Allow schedulers to be restarted; separate unit tests from integration tests [\#66](https://github.com/bensheldon/good_job/pull/66) ([bensheldon](https://github.com/bensheldon))
|
46
|
+
|
47
|
+
## [v1.0.3](https://github.com/bensheldon/good_job/tree/v1.0.3) (2020-07-26)
|
48
|
+
|
49
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.0.2...v1.0.3)
|
50
|
+
|
51
|
+
**Fixed bugs:**
|
52
|
+
|
53
|
+
- Preserve GoodJob::Jobs when a StandardError is raised [\#60](https://github.com/bensheldon/good_job/issues/60)
|
54
|
+
|
55
|
+
**Closed issues:**
|
56
|
+
|
57
|
+
- Have an initial setup generator [\#6](https://github.com/bensheldon/good_job/issues/6)
|
58
|
+
|
59
|
+
**Merged pull requests:**
|
60
|
+
|
61
|
+
- Re-perform a job if a StandardError bubbles up; better document job reliability [\#62](https://github.com/bensheldon/good_job/pull/62) ([bensheldon](https://github.com/bensheldon))
|
62
|
+
- Update the setup documentation to use correct bin setup command [\#61](https://github.com/bensheldon/good_job/pull/61) ([jm96441n](https://github.com/jm96441n))
|
63
|
+
|
64
|
+
## [v1.0.2](https://github.com/bensheldon/good_job/tree/v1.0.2) (2020-07-25)
|
65
|
+
|
66
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.0.1...v1.0.2)
|
67
|
+
|
68
|
+
**Fixed bugs:**
|
69
|
+
|
70
|
+
- Fix counting of available execution threads [\#58](https://github.com/bensheldon/good_job/pull/58) ([bensheldon](https://github.com/bensheldon))
|
71
|
+
|
72
|
+
**Merged pull requests:**
|
73
|
+
|
74
|
+
- Add migration generator [\#56](https://github.com/bensheldon/good_job/pull/56) ([thedanbob](https://github.com/thedanbob))
|
75
|
+
- Fix migration script in readme [\#55](https://github.com/bensheldon/good_job/pull/55) ([thedanbob](https://github.com/thedanbob))
|
76
|
+
|
77
|
+
## [v1.0.1](https://github.com/bensheldon/good_job/tree/v1.0.1) (2020-07-22)
|
4
78
|
|
5
79
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.0.0...v1.0.1)
|
6
80
|
|
@@ -32,12 +106,15 @@
|
|
32
106
|
|
33
107
|
- Run Github Action tests on PRs from forks [\#44](https://github.com/bensheldon/good_job/pull/44) ([bensheldon](https://github.com/bensheldon))
|
34
108
|
- Fix Rubygems homepage URL [\#43](https://github.com/bensheldon/good_job/pull/43) ([joshmn](https://github.com/joshmn))
|
35
|
-
- Move where\(scheduled\_at: Time.current\) into dynamic part of GoodJob::Job::Performer [\#42](https://github.com/bensheldon/good_job/pull/42) ([bensheldon](https://github.com/bensheldon))
|
36
109
|
|
37
110
|
## [v0.8.1](https://github.com/bensheldon/good_job/tree/v0.8.1) (2020-07-18)
|
38
111
|
|
39
112
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v0.8.0...v0.8.1)
|
40
113
|
|
114
|
+
**Merged pull requests:**
|
115
|
+
|
116
|
+
- Move where\(scheduled\_at: Time.current\) into dynamic part of GoodJob::Job::Performer [\#42](https://github.com/bensheldon/good_job/pull/42) ([bensheldon](https://github.com/bensheldon))
|
117
|
+
|
41
118
|
## [v0.8.0](https://github.com/bensheldon/good_job/tree/v0.8.0) (2020-07-17)
|
42
119
|
|
43
120
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v0.7.0...v0.8.0)
|
data/README.md
CHANGED
@@ -9,6 +9,8 @@ GoodJob is a multithreaded, Postgres-based, ActiveJob backend for Ruby on Rails.
|
|
9
9
|
- **Backed by Postgres.** Relies upon Postgres integrity and session-level Advisory Locks to provide run-once safety and stay within the limits of `schema.rb`.
|
10
10
|
- **For most workloads.** Targets full-stack teams, economy-minded solo developers, and applications that enqueue less than 1-million jobs/day.
|
11
11
|
|
12
|
+
For more of the story of GoodJob, read the [introductory blog post](https://island94.org/2020/07/introducing-goodjob-1-0).
|
13
|
+
|
12
14
|
## Installation
|
13
15
|
|
14
16
|
Add this line to your application's Gemfile:
|
@@ -25,35 +27,11 @@ $ bundle install
|
|
25
27
|
## Usage
|
26
28
|
|
27
29
|
1. Create a database migration:
|
28
|
-
|
29
|
-
|
30
|
+
|
31
|
+
```bash
|
32
|
+
$ bin/rails g good_job:install
|
30
33
|
```
|
31
34
|
|
32
|
-
Add to the newly created migration file:
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
class CreateGoodJobs < ActiveRecord::Migration[6.0]
|
36
|
-
def change
|
37
|
-
enable_extension 'pgcrypto'
|
38
|
-
|
39
|
-
create_table :good_jobs, id: :uuid do |t|
|
40
|
-
t.timestamps
|
41
|
-
|
42
|
-
t.text :queue_name
|
43
|
-
t.integer :priority
|
44
|
-
t.jsonb :serialized_params
|
45
|
-
t.timestamp :scheduled_at
|
46
|
-
t.timestamp :performed_at
|
47
|
-
t.timestamp :finished_at
|
48
|
-
t.text :error
|
49
|
-
|
50
|
-
add_index :good_jobs, :scheduled_at, where: "(finished_at IS NULL)"
|
51
|
-
add_index :good_jobs, [:queue_name, :scheduled_at], where: "(finished_at IS NULL)"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
```
|
56
|
-
|
57
35
|
Run the migration:
|
58
36
|
|
59
37
|
```bash
|
@@ -61,7 +39,8 @@ $ bundle install
|
|
61
39
|
```
|
62
40
|
|
63
41
|
1. Configure the ActiveJob adapter:
|
64
|
-
|
42
|
+
|
43
|
+
```ruby
|
65
44
|
# config/application.rb
|
66
45
|
config.active_job.queue_adapter = :good_job
|
67
46
|
```
|
@@ -80,48 +59,190 @@ $ bundle install
|
|
80
59
|
```
|
81
60
|
|
82
61
|
1. Queue your job 🎉:
|
62
|
+
|
83
63
|
```ruby
|
84
64
|
YourJob.set(queue: :some_queue, wait: 5.minutes, priority: 10).perform_later
|
85
65
|
```
|
86
66
|
|
87
67
|
1. In production, the scheduler is designed to run in its own process:
|
68
|
+
|
88
69
|
```bash
|
89
70
|
$ bundle exec good_job
|
90
71
|
```
|
91
72
|
|
92
73
|
Configuration options available with `help`:
|
93
|
-
|
94
|
-
|
74
|
+
|
75
|
+
```bash
|
76
|
+
$ bundle exec good_job help start
|
77
|
+
|
78
|
+
Usage:
|
79
|
+
good_job start
|
80
|
+
|
81
|
+
Options:
|
82
|
+
[--max-threads=N] # Maximum number of threads to use for working jobs (default: ActiveRecord::Base.connection_pool.size)
|
83
|
+
[--queues=queue1,queue2(;queue3,queue4:5;-queue1,queue2)] # Queues to work from. Separate multiple queues with commas; exclude queues with a leading minus; separate isolated execution pools with semicolons and threads with colons (default: *)
|
84
|
+
[--poll-interval=N] # Interval between polls for available jobs in seconds (default: 1)
|
85
|
+
|
86
|
+
Start job worker
|
87
|
+
```
|
88
|
+
|
89
|
+
1. Optimize execution to reduce congestion and execution latency.
|
90
|
+
|
91
|
+
By default, GoodJob creates a single thread execution pool that will execute jobs from any queue. Depending on your application's workload, job types, and service level objectives, you may wish to optimize execution resources; for example, providing dedicated execution resources for transactional emails so they are not delayed by long-running batch jobs. Some options:
|
92
|
+
|
93
|
+
- Multiple execution pools within a single process:
|
94
|
+
|
95
|
+
```bash
|
96
|
+
$ bundle exec good_job --queues=transactional_messages:2;batch_processing:1;-transactional_messages,batch_processing:2;* --max-threads=5
|
97
|
+
```
|
98
|
+
|
99
|
+
This configuration will result in a single process with 4 isolated thread execution pools. Isolated execution pools are separated with a semicolon (`;`) and queue names and thread counts with a colon (`:`)
|
100
|
+
|
101
|
+
- `transactional_messages:2`: execute jobs enqueued on `transactional_messages` with up to 2 threads.
|
102
|
+
- `batch_processing:1` execute jobs enqueued on `batch_processing` with a single thread.
|
103
|
+
- `-transactional_messages,batch_processing`: execute jobs enqueued on _any_ queue _excluding_ `transactional_messages` or `batch_processing` with up to 2 threads.
|
104
|
+
- `*`: execute jobs on any queue on up to 5 threads, as configured by `--max-threads=5`
|
105
|
+
|
106
|
+
For moderate workloads, multiple isolated thread execution pools offers a good balance between congestion management and economy.
|
107
|
+
|
108
|
+
Configuration can be injected by environment variables too:
|
109
|
+
|
110
|
+
```bash
|
111
|
+
$ GOOD_JOB_QUEUES="transactional_messages:2;batch_processing:1;-transactional_messages,batch_processing:2;*" GOOD_JOB_MAX_THREADS=5 bundle exec good_job
|
112
|
+
```
|
113
|
+
|
114
|
+
- Multiple processes; for example, on Heroku:
|
115
|
+
|
116
|
+
```procfile
|
117
|
+
# Procfile
|
118
|
+
|
119
|
+
# Separate dyno types
|
120
|
+
worker: bundle exec good_job --max-threads=5
|
121
|
+
transactional_worker: bundle exec good_job --queues=transactional_messages --max-threads=2
|
122
|
+
batch_worker: bundle exec good_job --queues=batch_processing --max-threads=1
|
123
|
+
|
124
|
+
# Combined multi-process dyno
|
125
|
+
combined_worker: bundle exec good_job --max-threads=5 & bundle exec good_job --queues=transactional_messages --max-threads=2 & bundle exec good_job --queues=batch_processing --max-threads=1 & wait -n
|
126
|
+
```
|
127
|
+
|
128
|
+
Running multiple processes can optimize for CPU performance at the expense of greater memory and system resource usage.
|
129
|
+
|
130
|
+
_Keep in mind, queue operations and management is an advanced discipline. This stuff is complex, especially for heavy workloads and unique processing requirements. Good job 👍_
|
131
|
+
|
132
|
+
### Error handling, retries, and reliability
|
133
|
+
|
134
|
+
GoodJob guarantees that a completely-performed job will run once and only once. GoodJob fully supports ActiveJob's built-in functionality for error handling, retries and timeouts. Writing reliable, transactional, and idempotent `ActiveJob#perform` methods is outside the scope of GoodJob.
|
135
|
+
|
136
|
+
#### Error handling
|
137
|
+
|
138
|
+
By default, if a job raises an error while it is being performed, _and it bubbles up to the GoodJob backend_, GoodJob will be immediately re-perform the job until it finishes successfully.
|
139
|
+
|
140
|
+
- `Exception`-type errors, such as a SIGINT, will always cause a job to be re-performed.
|
141
|
+
- `StandardError`-type errors, by default, will cause a job to be re-performed, though this is configurable:
|
95
142
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
143
|
+
```ruby
|
144
|
+
# config/initializers/good_job.rb
|
145
|
+
GoodJob.reperform_jobs_on_standard_error = true # => default
|
146
|
+
```
|
147
|
+
|
148
|
+
To report errors that _do_ bubble up to the GoodJob backend, assign a callable to `GoodJob.on_thread_error`. For example:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
# config/initializers/good_job.rb
|
152
|
+
|
153
|
+
# With Sentry (or Bugsnag, Airbrake, Honeybadger, etc.)
|
154
|
+
GoodJob.on_thread_error = -> (exception) { Raven.capture_exception(exception) }
|
155
|
+
```
|
156
|
+
|
157
|
+
### Retrying jobs
|
158
|
+
|
159
|
+
ActiveJob can be configured to retry an infinite number of times, with an exponential backoff. Using ActiveJob's `retry_on` will ensure that errors do not bubble up to the GoodJob backend:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
class ApplicationJob < ActiveJob::Base
|
163
|
+
retry_on StandardError, wait: :exponentially_longer, attempts: Float::INFINITY
|
164
|
+
# ...
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
When specifying a limited number of retries, care must be taken to ensure that an error does not bubble up to the GoodJob backend because that will result in the job being re-performed:
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
class ApplicationJob < ActiveJob::Base
|
172
|
+
retry_on StandardError, attempts: 5 do |_job, _exception|
|
173
|
+
# Log error, etc.
|
174
|
+
# You must implement this block, otherwise,
|
175
|
+
# Active Job will re-raise the error.
|
176
|
+
# Do not re-raise the error, otherwise
|
177
|
+
# GoodJob will immediately re-perform the job.
|
178
|
+
end
|
179
|
+
# ...
|
180
|
+
end
|
181
|
+
```
|
104
182
|
|
105
|
-
|
183
|
+
GoodJob can be configured to allow omitting `retry_on`'s block argument and implicitly discard un-handled errors:
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
# config/initializers/good_job.rb
|
187
|
+
|
188
|
+
# Do NOT re-perform a job if a StandardError bubbles up to the GoodJob backend
|
189
|
+
GoodJob.reperform_jobs_on_standard_error = false
|
190
|
+
```
|
106
191
|
|
107
|
-
|
192
|
+
When using an exception monitoring service (e.g. Sentry, Bugsnag, Airbrake, Honeybadger, etc), the use of `rescue_on` may be incompatible with their ActiveJob integration. It's safest to explicitly wrap jobs with an exception reporter. For example:
|
108
193
|
|
109
194
|
```ruby
|
110
195
|
class ApplicationJob < ActiveJob::Base
|
111
|
-
# Retry errors an infinite number of times with exponential back-off
|
112
196
|
retry_on StandardError, wait: :exponentially_longer, attempts: Float::INFINITY
|
197
|
+
|
198
|
+
around_perform do |_job, block|
|
199
|
+
block.call
|
200
|
+
rescue StandardError => e
|
201
|
+
Raven.capture_exception(e)
|
202
|
+
raise
|
203
|
+
end
|
204
|
+
# ...
|
205
|
+
end
|
206
|
+
```
|
207
|
+
|
208
|
+
|
209
|
+
ActiveJob's `discard_on` functionality is supported too.
|
210
|
+
|
211
|
+
#### ActionMailer retries
|
212
|
+
|
213
|
+
Using a Mailer's `#deliver_later` will enqueue an instance of `ActionMailer::DeliveryJob` which inherits from `ActiveJob::Base` rather than your applications `ApplicationJob`. You can use an initializer to configure retries on `ActionMailer::DeliveryJob`:
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
# config/initializers/good_job.rb
|
217
|
+
ActionMailer::DeliveryJob.retry_on StandardError, wait: :exponentially_longer, attempts: Float::INFINITY
|
218
|
+
|
219
|
+
# With Sentry (or Bugsnag, Airbrake, Honeybadger, etc.)
|
220
|
+
ActionMailer::DeliveryJob.around_perform do |_job, block|
|
221
|
+
block.call
|
222
|
+
rescue StandardError => e
|
223
|
+
Raven.capture_exception(e)
|
224
|
+
raise
|
225
|
+
end
|
226
|
+
```
|
113
227
|
|
114
|
-
|
228
|
+
#### Timeouts
|
229
|
+
|
230
|
+
Job timeouts can be configured with an `around_perform`:
|
231
|
+
|
232
|
+
```ruby
|
233
|
+
class ApplicationJob < ActiveJob::Base
|
115
234
|
JobTimeoutError = Class.new(StandardError)
|
235
|
+
|
116
236
|
around_perform do |_job, block|
|
237
|
+
# Timeout jobs after 10 minutes
|
117
238
|
Timeout.timeout(10.minutes, JobTimeoutError) do
|
118
239
|
block.call
|
119
240
|
end
|
120
241
|
end
|
121
242
|
end
|
122
243
|
```
|
123
|
-
|
124
|
-
### Configuring
|
244
|
+
|
245
|
+
### Configuring job execution threads
|
125
246
|
|
126
247
|
GoodJob executes enqueued jobs using threads. There is a lot than can be said about [multithreaded behavior in Ruby on Rails](https://guides.rubyonrails.org/threading_and_code_execution.html), but briefly:
|
127
248
|
|
@@ -132,6 +253,51 @@ GoodJob executes enqueued jobs using threads. There is a lot than can be said ab
|
|
132
253
|
3. `$ RAILS_MAX_THREADS=4 bundle exec good_job`
|
133
254
|
4. Implicitly via Rails's database connection pool size (`ActiveRecord::Base.connection_pool.size`)
|
134
255
|
|
256
|
+
### Executing jobs async / in-process
|
257
|
+
|
258
|
+
GoodJob is able to run "async" in the same process as the webserver (e.g. `bin/rail s`). GoodJob's async execution mode offers benefits of economy by not requiring a separate job worker process, but with the tradeoff of increased complexity. Async mode can be configured in two ways:
|
259
|
+
|
260
|
+
- Directly configure the ActiveJob adapter:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
# config/environments/production.rb
|
264
|
+
config.active_job.queue_adapter = GoodJob::Adapter.new(execution_mode: :async, max_threads: 4, poll_interval: 30)
|
265
|
+
```
|
266
|
+
- Or, when using `...queue_adapter = :good_job`, via environment variables:
|
267
|
+
|
268
|
+
```bash
|
269
|
+
$ GOOD_JOB_EXECUTION_MODE=async GOOD_JOB_MAX_THREADS=4 GOOD_JOB_POLL_INTERVAL=30 bin/rails server
|
270
|
+
```
|
271
|
+
|
272
|
+
Depending on your application configuration, you may need to take additional steps:
|
273
|
+
|
274
|
+
- Ensure that you have enough database connections for both web and job execution threads:
|
275
|
+
|
276
|
+
```yaml
|
277
|
+
# config/database.yml
|
278
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5).to_i + ENV.fetch("GOOD_JOB_MAX_THREADS", 4).to_i %>
|
279
|
+
```
|
280
|
+
|
281
|
+
- When running Puma with workers (`WEB_CONCURRENCY > 0`) or another process-forking webserver, GoodJob's threadpool schedulers should be stopped before forking, restarted after fork, and cleanly shut down on exit. Stopping GoodJob's scheduler pre-fork is recommended to ensure that GoodJob does not continue executing jobs in the parent/controller process. For example, with Puma:
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
# config/puma.rb
|
285
|
+
|
286
|
+
before_fork do
|
287
|
+
GoodJob::Scheduler.instances.each { |s| s.shutdown }
|
288
|
+
end
|
289
|
+
|
290
|
+
on_worker_boot do
|
291
|
+
GoodJob::Scheduler.instances.each { |s| s.restart }
|
292
|
+
end
|
293
|
+
|
294
|
+
on_worker_shutdown do
|
295
|
+
GoodJob::Scheduler.instances.each { |s| s.shutdown }
|
296
|
+
end
|
297
|
+
```
|
298
|
+
|
299
|
+
GoodJob is compatible with Puma's `preload_app!` method.
|
300
|
+
|
135
301
|
### Migrating to GoodJob from a different ActiveJob backend
|
136
302
|
|
137
303
|
If your application is already using an ActiveJob backend, you will need to install GoodJob to enqueue and perform newly created jobs _and_ finish performing pre-existing jobs on the previous backend.
|
@@ -147,7 +313,8 @@ If your application is already using an ActiveJob backend, you will need to inst
|
|
147
313
|
```
|
148
314
|
|
149
315
|
1. Continue running executors for both backends. For example, on Heroku it's possible to run [two processes](https://help.heroku.com/CTFS2TJK/how-do-i-run-multiple-processes-on-a-dyno) within the same dyno:
|
150
|
-
|
316
|
+
|
317
|
+
```procfile
|
151
318
|
# Procfile
|
152
319
|
# ...
|
153
320
|
worker: bundle exec que ./config/environment.rb & bundle exec good_job & wait -n
|
@@ -173,15 +340,24 @@ It is also necessary to delete these preserved jobs from the database after a ce
|
|
173
340
|
- For example, in a Rake task:
|
174
341
|
|
175
342
|
```ruby
|
176
|
-
|
343
|
+
GoodJob::Job.finished(1.day.ago).delete_all
|
177
344
|
```
|
345
|
+
|
178
346
|
- For example, using the `good_job` command-line utility:
|
179
347
|
|
180
348
|
```bash
|
181
349
|
$ bundle exec good_job cleanup_preserved_jobs --before-seconds-ago=86400
|
182
350
|
```
|
183
351
|
|
184
|
-
##
|
352
|
+
## Contributing
|
353
|
+
|
354
|
+
Contributions are welcomed and appreciated 🙏
|
355
|
+
|
356
|
+
- Review the [Prioritized Project Backlog](https://github.com/bensheldon/good_job/projects/1).
|
357
|
+
- Open a new Issue or contribute to an [existing Issue](https://github.com/bensheldon/good_job/issues). Questions or suggestions are fantastic.
|
358
|
+
- Participate according to our [Code of Conduct](https://github.com/bensheldon/good_job/projects/1).
|
359
|
+
|
360
|
+
### Gem development
|
185
361
|
|
186
362
|
To run tests:
|
187
363
|
|
@@ -190,7 +366,7 @@ To run tests:
|
|
190
366
|
$ git clone git@github.com:bensheldon/good_job.git
|
191
367
|
|
192
368
|
# Set up the local environment
|
193
|
-
$ bin/
|
369
|
+
$ bin/setup
|
194
370
|
|
195
371
|
# Run the tests
|
196
372
|
$ bin/rspec
|
@@ -204,7 +380,6 @@ $ bundle exec appraisal
|
|
204
380
|
|
205
381
|
# Run tests
|
206
382
|
$ bundle exec appraisal bin/rspec
|
207
|
-
|
208
383
|
```
|
209
384
|
|
210
385
|
For developing locally within another Ruby on Rails project:
|
@@ -219,24 +394,23 @@ $ bundle install
|
|
219
394
|
# => Using good_job 0.1.0 from https://github.com/bensheldon/good_job.git (at /Users/You/Projects/good_job@dc57fb0)
|
220
395
|
```
|
221
396
|
|
222
|
-
|
397
|
+
### Releasing
|
223
398
|
|
224
|
-
Package maintainers can release this gem
|
399
|
+
Package maintainers can release this gem by running:
|
225
400
|
|
226
401
|
```bash
|
227
402
|
# Sign into rubygems
|
228
403
|
$ gem signin
|
229
404
|
|
405
|
+
# Add a .env file with the following:
|
406
|
+
# CHANGELOG_GITHUB_TOKEN= # Github Personal Access Token
|
407
|
+
|
230
408
|
# Update version number, changelog, and create git commit:
|
231
|
-
$ bundle exec rake
|
409
|
+
$ bundle exec rake release[minor] # major,minor,patch
|
232
410
|
|
233
411
|
# ..and follow subsequent directions.
|
234
412
|
```
|
235
413
|
|
236
|
-
## Contributing
|
237
|
-
|
238
|
-
Contribution directions go here.
|
239
|
-
|
240
414
|
## License
|
241
415
|
|
242
416
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|