good_job 1.0.3 → 1.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc7b3997aaa38583efb4c91e66a2a5f9b8bfd75d4c14c9baaf8f1af7c236a42e
4
- data.tar.gz: 285b441a5e5add440142960884370a1b74168266252fa48ce569cbb56e80f240
3
+ metadata.gz: 7134108a565e8b1efaa825cec90630cab0965fcfca5ff02f09751730f8839bdc
4
+ data.tar.gz: d887e3b6cbb6d3d877793b186de2c0ca5a65178b968b2000821c6f9000c0fdd1
5
5
  SHA512:
6
- metadata.gz: f54e83d6ac19d80da2123a395ccf6ffd7eb2faab8e68bd5d50a572c8f0bf64fbc907125a47b7ff91dccac5497af113d043bba4f62ee6ae10fecaf3c004a1114d
7
- data.tar.gz: 0b65a60bde26db0cfcfa55f166e80043bcbccb6e2c80f5de1840d2deae3ee28880c904bb53ffc2478ad834ffef8cfe567cee9a179932e20e4f92fdf8504838e4
6
+ metadata.gz: cce4a02b62ded08da0b2665cb346bfbeda6fdffa15182c8ab680962f6ba1f3534a8b9ac4cad8ecfa60d34b15cdfaabff5c8c80e4b3f7bdaa99c2d7a0e4208fe9
7
+ data.tar.gz: d9f13feb39a8700fe889c7b4250004095cdddeb5e1e9f06426610d10c13ce7c14d20db32810aa93dd4d1b7a075f585821bf4581634373a3585540bab0018f46c
@@ -1,6 +1,77 @@
1
1
  # Changelog
2
2
 
3
- ## [v1.0.3](https://github.com/bensheldon/good_job/tree/v1.0.3) (2020-07-25)
3
+ ## [v1.1.4](https://github.com/bensheldon/good_job/tree/v1.1.4) (2020-08-19)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.1.3...v1.1.4)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Explicitly name threads for easier debugging [\#64](https://github.com/bensheldon/good_job/issues/64)
10
+ - Investigate Listen/Notify as alternative to polling [\#54](https://github.com/bensheldon/good_job/issues/54)
11
+
12
+ **Merged pull requests:**
13
+
14
+ - Add Postgres LISTEN/NOTIFY support [\#82](https://github.com/bensheldon/good_job/pull/82) ([bensheldon](https://github.com/bensheldon))
15
+ - Allow Schedulers to filter \#create\_thread to avoid flood of queries when running async with multiple schedulers [\#81](https://github.com/bensheldon/good_job/pull/81) ([bensheldon](https://github.com/bensheldon))
16
+ - Fully name scheduler threadpools and thread names; refactor CLI STDOUT [\#80](https://github.com/bensheldon/good_job/pull/80) ([bensheldon](https://github.com/bensheldon))
17
+
18
+ ## [v1.1.3](https://github.com/bensheldon/good_job/tree/v1.1.3) (2020-08-14)
19
+
20
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.1.2...v1.1.3)
21
+
22
+ **Fixed bugs:**
23
+
24
+ - Job exceptions not properly attached to good\_jobs record [\#72](https://github.com/bensheldon/good_job/issues/72)
25
+
26
+ **Merged pull requests:**
27
+
28
+ - Capture errors via instrumentation from retry\_on and discard\_on [\#79](https://github.com/bensheldon/good_job/pull/79) ([bensheldon](https://github.com/bensheldon))
29
+ - Document GoodJob::Scheduler with Yard [\#78](https://github.com/bensheldon/good_job/pull/78) ([bensheldon](https://github.com/bensheldon))
30
+
31
+ ## [v1.1.2](https://github.com/bensheldon/good_job/tree/v1.1.2) (2020-08-13)
32
+
33
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.1.1...v1.1.2)
34
+
35
+ **Implemented enhancements:**
36
+
37
+ - Allow the omission of queue names within a scheduler [\#73](https://github.com/bensheldon/good_job/issues/73)
38
+
39
+ **Merged pull requests:**
40
+
41
+ - Allow named queues to be excluded with a minus [\#77](https://github.com/bensheldon/good_job/pull/77) ([bensheldon](https://github.com/bensheldon))
42
+
43
+ ## [v1.1.1](https://github.com/bensheldon/good_job/tree/v1.1.1) (2020-08-12)
44
+
45
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.1.0...v1.1.1)
46
+
47
+ **Implemented enhancements:**
48
+
49
+ - Allow multiple schedulers within the same process. e.g. `queues=mice:2,elephants:4` [\#45](https://github.com/bensheldon/good_job/issues/45)
50
+
51
+ **Merged pull requests:**
52
+
53
+ - Allow instantiation of multiple schedulers via --queues [\#76](https://github.com/bensheldon/good_job/pull/76) ([bensheldon](https://github.com/bensheldon))
54
+
55
+ ## [v1.1.0](https://github.com/bensheldon/good_job/tree/v1.1.0) (2020-08-10)
56
+
57
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.0.3...v1.1.0)
58
+
59
+ **Closed issues:**
60
+
61
+ - Document reliability guarantees [\#59](https://github.com/bensheldon/good_job/issues/59)
62
+ - Document how to hook in exception monitor \(Sentry, Rollbar, etc\) [\#47](https://github.com/bensheldon/good_job/issues/47)
63
+ - Allow an Async mode [\#27](https://github.com/bensheldon/good_job/issues/27)
64
+
65
+ **Merged pull requests:**
66
+
67
+ - Add a callable hook on thread errors [\#71](https://github.com/bensheldon/good_job/pull/71) ([bensheldon](https://github.com/bensheldon))
68
+ - Clarify reliability guarantees [\#70](https://github.com/bensheldon/good_job/pull/70) ([bensheldon](https://github.com/bensheldon))
69
+ - 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))
70
+ - Create an Async execution mode [\#68](https://github.com/bensheldon/good_job/pull/68) ([bensheldon](https://github.com/bensheldon))
71
+ - Move all stdout to LogSubscriber [\#67](https://github.com/bensheldon/good_job/pull/67) ([bensheldon](https://github.com/bensheldon))
72
+ - 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))
73
+
74
+ ## [v1.0.3](https://github.com/bensheldon/good_job/tree/v1.0.3) (2020-07-26)
4
75
 
5
76
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.0.2...v1.0.3)
6
77
 
@@ -14,6 +85,7 @@
14
85
 
15
86
  **Merged pull requests:**
16
87
 
88
+ - Extract options parsing to Configuration object [\#74](https://github.com/bensheldon/good_job/pull/74) ([bensheldon](https://github.com/bensheldon))
17
89
  - 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))
18
90
  - Update the setup documentation to use correct bin setup command [\#61](https://github.com/bensheldon/good_job/pull/61) ([jm96441n](https://github.com/jm96441n))
19
91
 
@@ -25,10 +97,6 @@
25
97
 
26
98
  - Fix counting of available execution threads [\#58](https://github.com/bensheldon/good_job/pull/58) ([bensheldon](https://github.com/bensheldon))
27
99
 
28
- **Closed issues:**
29
-
30
- - repeating/recurring jobs [\#53](https://github.com/bensheldon/good_job/issues/53)
31
-
32
100
  **Merged pull requests:**
33
101
 
34
102
  - Add migration generator [\#56](https://github.com/bensheldon/good_job/pull/56) ([thedanbob](https://github.com/thedanbob))
@@ -40,7 +108,7 @@
40
108
 
41
109
  **Merged pull requests:**
42
110
 
43
- - Change threadpool idletime default to 60 seconds from 0 [\#49](https://github.com/bensheldon/good_job/pull/49) ([bensheldon](https://github.com/bensheldon))
111
+ - Allow preservation of finished job records [\#46](https://github.com/bensheldon/good_job/pull/46) ([bensheldon](https://github.com/bensheldon))
44
112
 
45
113
  ## [v1.0.0](https://github.com/bensheldon/good_job/tree/v1.0.0) (2020-07-20)
46
114
 
@@ -50,10 +118,6 @@
50
118
 
51
119
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v0.8.2...v0.9.0)
52
120
 
53
- **Merged pull requests:**
54
-
55
- - Allow preservation of finished job records [\#46](https://github.com/bensheldon/good_job/pull/46) ([bensheldon](https://github.com/bensheldon))
56
-
57
121
  ## [v0.8.2](https://github.com/bensheldon/good_job/tree/v0.8.2) (2020-07-18)
58
122
 
59
123
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v0.8.1...v0.8.2)
@@ -81,6 +145,7 @@
81
145
 
82
146
  **Merged pull requests:**
83
147
 
148
+ - Change threadpool idletime default to 60 seconds from 0 [\#49](https://github.com/bensheldon/good_job/pull/49) ([bensheldon](https://github.com/bensheldon))
84
149
  - Replace Adapter inline boolean kwarg with execution\_mode instead [\#41](https://github.com/bensheldon/good_job/pull/41) ([bensheldon](https://github.com/bensheldon))
85
150
 
86
151
  ## [v0.7.0](https://github.com/bensheldon/good_job/tree/v0.7.0) (2020-07-16)
@@ -113,7 +178,6 @@
113
178
  - Add configuration options to good\_job executable [\#33](https://github.com/bensheldon/good_job/pull/33) ([bensheldon](https://github.com/bensheldon))
114
179
  - Extract Job querying behavior out of Scheduler [\#31](https://github.com/bensheldon/good_job/pull/31) ([bensheldon](https://github.com/bensheldon))
115
180
  - Allow configuration of Rails queue adapter with `:good\_job` [\#28](https://github.com/bensheldon/good_job/pull/28) ([bensheldon](https://github.com/bensheldon))
116
- - Update development Ruby to 2.6.5 [\#22](https://github.com/bensheldon/good_job/pull/22) ([bensheldon](https://github.com/bensheldon))
117
181
 
118
182
  ## [v0.5.0](https://github.com/bensheldon/good_job/tree/v0.5.0) (2020-07-13)
119
183
 
@@ -138,6 +202,7 @@
138
202
 
139
203
  **Merged pull requests:**
140
204
 
205
+ - Update development Ruby to 2.6.5 [\#22](https://github.com/bensheldon/good_job/pull/22) ([bensheldon](https://github.com/bensheldon))
141
206
  - Simplify the internal API, removing JobWrapper and InlineScheduler [\#21](https://github.com/bensheldon/good_job/pull/21) ([bensheldon](https://github.com/bensheldon))
142
207
  - Generate a new future for every executed job [\#20](https://github.com/bensheldon/good_job/pull/20) ([bensheldon](https://github.com/bensheldon))
143
208
  - Configuration for maximum number of job execution threads [\#18](https://github.com/bensheldon/good_job/pull/18) ([bensheldon](https://github.com/bensheldon))
data/README.md CHANGED
@@ -6,7 +6,7 @@ GoodJob is a multithreaded, Postgres-based, ActiveJob backend for Ruby on Rails.
6
6
 
7
7
  - **Designed for ActiveJob.** Complete support for [async, queues, delays, priorities, timeouts, and retries](https://edgeguides.rubyonrails.org/active_job_basics.html) with near-zero configuration.
8
8
  - **Built for Rails.** Fully adopts Ruby on Rails [threading and code execution guidelines](https://guides.rubyonrails.org/threading_and_code_execution.html) with [Concurrent::Ruby](https://github.com/ruby-concurrency/concurrent-ruby).
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`.
9
+ - **Backed by Postgres.** Relies upon Postgres integrity, session-level Advisory Locks to provide run-once safety and stay within the limits of `schema.rb`, and LISTEN/NOTIFY to reduce queuing latency.
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
12
  For more of the story of GoodJob, read the [introductory blog post](https://island94.org/2020/07/introducing-goodjob-1-0).
@@ -27,7 +27,8 @@ $ bundle install
27
27
  ## Usage
28
28
 
29
29
  1. Create a database migration:
30
- ```bash
30
+
31
+ ```bash
31
32
  $ bin/rails g good_job:install
32
33
  ```
33
34
 
@@ -38,7 +39,8 @@ $ bundle install
38
39
  ```
39
40
 
40
41
  1. Configure the ActiveJob adapter:
41
- ```ruby
42
+
43
+ ```ruby
42
44
  # config/application.rb
43
45
  config.active_job.queue_adapter = :good_job
44
46
  ```
@@ -57,31 +59,79 @@ $ bundle install
57
59
  ```
58
60
 
59
61
  1. Queue your job 🎉:
62
+
60
63
  ```ruby
61
64
  YourJob.set(queue: :some_queue, wait: 5.minutes, priority: 10).perform_later
62
65
  ```
63
66
 
64
67
  1. In production, the scheduler is designed to run in its own process:
68
+
65
69
  ```bash
66
70
  $ bundle exec good_job
67
71
  ```
68
72
 
69
73
  Configuration options available with `help`:
70
- ```bash
71
- $ bundle exec good_job help start
74
+
75
+ ```bash
76
+ $ bundle exec good_job help start
72
77
 
73
- # Usage:
74
- # good_job start
75
- #
76
- # Options:
77
- # [--max-threads=N] # Maximum number of threads to use for working jobs (default: ActiveRecord::Base.connection_pool.size)
78
- # [--queues=queue1,queue2] # Queues to work from. Separate multiple queues with commas (default: *)
79
- # [--poll-interval=N] # Interval between polls for available jobs in seconds (default: 1)
80
- ```
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 👍_
81
131
 
82
132
  ### Error handling, retries, and reliability
83
133
 
84
- GoodJob guarantees _at-least-once_ performance of jobs. GoodJob fully supports ActiveJob's built-in functionality for error handling, retries and timeouts.
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.
85
135
 
86
136
  #### Error handling
87
137
 
@@ -95,6 +145,15 @@ By default, if a job raises an error while it is being performed, _and it bubble
95
145
  GoodJob.reperform_jobs_on_standard_error = true # => default
96
146
  ```
97
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
+
98
157
  ### Retrying jobs
99
158
 
100
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:
@@ -123,12 +182,29 @@ end
123
182
 
124
183
  GoodJob can be configured to allow omitting `retry_on`'s block argument and implicitly discard un-handled errors:
125
184
 
126
- ```ruby
127
- # config/initializers/good_job.rb
128
-
129
- # Do NOT re-perform a job if a StandardError bubbles up to the GoodJob backend
130
- GoodJob.reperform_jobs_on_standard_error = false
131
- ```
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
+ ```
191
+
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:
193
+
194
+ ```ruby
195
+ class ApplicationJob < ActiveJob::Base
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
+
132
208
 
133
209
  ActiveJob's `discard_on` functionality is supported too.
134
210
 
@@ -139,6 +215,14 @@ Using a Mailer's `#deliver_later` will enqueue an instance of `ActionMailer::Del
139
215
  ```ruby
140
216
  # config/initializers/good_job.rb
141
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
142
226
  ```
143
227
 
144
228
  #### Timeouts
@@ -158,7 +242,7 @@ class ApplicationJob < ActiveJob::Base
158
242
  end
159
243
  ```
160
244
 
161
- ### Configuring Job Execution Threads
245
+ ### Configuring job execution threads
162
246
 
163
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:
164
248
 
@@ -169,6 +253,56 @@ GoodJob executes enqueued jobs using threads. There is a lot than can be said ab
169
253
  3. `$ RAILS_MAX_THREADS=4 bundle exec good_job`
170
254
  4. Implicitly via Rails's database connection pool size (`ActiveRecord::Base.connection_pool.size`)
171
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.shutdown
288
+ end
289
+
290
+ on_worker_boot do
291
+ GoodJob.restart
292
+ end
293
+
294
+ on_worker_shutdown do
295
+ GoodJob.shutdown
296
+ end
297
+
298
+ MAIN_PID = Process.pid
299
+ at_exit do
300
+ GoodJob.shutdown if Process.pid == MAIN_PID
301
+ end
302
+ ```
303
+
304
+ GoodJob is compatible with Puma's `preload_app!` method.
305
+
172
306
  ### Migrating to GoodJob from a different ActiveJob backend
173
307
 
174
308
  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.
@@ -184,7 +318,8 @@ If your application is already using an ActiveJob backend, you will need to inst
184
318
  ```
185
319
 
186
320
  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:
187
- ```procfile
321
+
322
+ ```procfile
188
323
  # Procfile
189
324
  # ...
190
325
  worker: bundle exec que ./config/environment.rb & bundle exec good_job & wait -n
@@ -210,15 +345,24 @@ It is also necessary to delete these preserved jobs from the database after a ce
210
345
  - For example, in a Rake task:
211
346
 
212
347
  ```ruby
213
- # GoodJob::Job.finished(1.day.ago).delete_all
348
+ GoodJob::Job.finished(1.day.ago).delete_all
214
349
  ```
350
+
215
351
  - For example, using the `good_job` command-line utility:
216
352
 
217
353
  ```bash
218
354
  $ bundle exec good_job cleanup_preserved_jobs --before-seconds-ago=86400
219
355
  ```
220
356
 
221
- ## Development
357
+ ## Contributing
358
+
359
+ Contributions are welcomed and appreciated 🙏
360
+
361
+ - Review the [Prioritized Project Backlog](https://github.com/bensheldon/good_job/projects/1).
362
+ - Open a new Issue or contribute to an [existing Issue](https://github.com/bensheldon/good_job/issues). Questions or suggestions are fantastic.
363
+ - Participate according to our [Code of Conduct](https://github.com/bensheldon/good_job/projects/1).
364
+
365
+ ### Gem development
222
366
 
223
367
  To run tests:
224
368
 
@@ -241,7 +385,6 @@ $ bundle exec appraisal
241
385
 
242
386
  # Run tests
243
387
  $ bundle exec appraisal bin/rspec
244
-
245
388
  ```
246
389
 
247
390
  For developing locally within another Ruby on Rails project:
@@ -256,24 +399,23 @@ $ bundle install
256
399
  # => Using good_job 0.1.0 from https://github.com/bensheldon/good_job.git (at /Users/You/Projects/good_job@dc57fb0)
257
400
  ```
258
401
 
259
- ## Releasing
402
+ ### Releasing
260
403
 
261
- Package maintainers can release this gem with the following [gem-release](https://github.com/svenfuchs/gem-release) command:
404
+ Package maintainers can release this gem by running:
262
405
 
263
406
  ```bash
264
407
  # Sign into rubygems
265
408
  $ gem signin
266
409
 
410
+ # Add a .env file with the following:
411
+ # CHANGELOG_GITHUB_TOKEN= # Github Personal Access Token
412
+
267
413
  # Update version number, changelog, and create git commit:
268
- $ bundle exec rake commit_version[minor] # major,minor,patch
414
+ $ bundle exec rake release[minor] # major,minor,patch
269
415
 
270
416
  # ..and follow subsequent directions.
271
417
  ```
272
418
 
273
- ## Contributing
274
-
275
- Contribution directions go here.
276
-
277
419
  ## License
278
420
 
279
421
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).