good_job 0.6.0 → 0.7.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 +14 -0
- data/README.md +36 -1
- data/lib/good_job/adapter.rb +1 -1
- data/lib/good_job/job.rb +8 -5
- data/lib/good_job/lockable.rb +7 -2
- data/lib/good_job/version.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f7dda29494df3fc05a199d6bf0efbc825a47653c3af507a0d1ceb92456d4307
|
4
|
+
data.tar.gz: 881ad046bab6b17c5d532d035fddef54420639288a0a4bd8f4f07b980c1fa239
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0cfc3c4d61666844a6bd7c532670e0b1be40fd6f805eff63919d3600d06933b8029f0febbc81efbf52b1f3d459317caeb522affe20dde9d3f4d7672622fd708
|
7
|
+
data.tar.gz: c4c9a9fddb2108769e3672baeaeaca2f7c966ee708f95867ed57970e688debcf1ce41a3eacd65d88c0192700f1b293cd4a9ad63fee9e4af93d44934b0876120f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v0.7.0](https://github.com/bensheldon/good_job/tree/v0.7.0) (2020-07-15)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v0.6.0...v0.7.0)
|
6
|
+
|
7
|
+
**Closed issues:**
|
8
|
+
|
9
|
+
- Always store a default priority \(0\) and scheduled\_at\(Time.current\) [\#30](https://github.com/bensheldon/good_job/issues/30)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Add more examples to Readme [\#39](https://github.com/bensheldon/good_job/pull/39) ([bensheldon](https://github.com/bensheldon))
|
14
|
+
- Add additional Rubocops and lint [\#38](https://github.com/bensheldon/good_job/pull/38) ([bensheldon](https://github.com/bensheldon))
|
15
|
+
- Always store a default queue\_name, priority and scheduled\_at; index by queue\_name and scheduled\_at [\#37](https://github.com/bensheldon/good_job/pull/37) ([bensheldon](https://github.com/bensheldon))
|
16
|
+
|
3
17
|
## [v0.6.0](https://github.com/bensheldon/good_job/tree/v0.6.0) (2020-07-15)
|
4
18
|
|
5
19
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v0.5.0...v0.6.0)
|
data/README.md
CHANGED
@@ -7,7 +7,15 @@ Inspired by [Delayed::Job](https://github.com/collectiveidea/delayed_job) and [Q
|
|
7
7
|
- Stand on the shoulders of ActiveJob. For example, [exception](https://edgeguides.rubyonrails.org/active_job_basics.html#exceptions) and [retry](https://edgeguides.rubyonrails.org/active_job_basics.html#retrying-or-discarding-failed-jobs) behavior.
|
8
8
|
- Stand on the shoulders of Ruby on Rails. For example, ActiveRecord ORM, connection pools, and [multithreaded support](https://guides.rubyonrails.org/threading_and_code_execution.html) with [Concurrent-Ruby](https://github.com/ruby-concurrency/concurrent-ruby).
|
9
9
|
- Stand on the shoulders of Postgres. For example, Advisory Locks.
|
10
|
-
- Convention over simplicity over performance.
|
10
|
+
- Convention over simplicity over performance.
|
11
|
+
|
12
|
+
GoodJob supports all ActiveJob functionality:
|
13
|
+
- Async. GoodJob has the ability to run the job in a non-blocking manner.
|
14
|
+
- Queues. Jobs may set which queue they are run in with queue_as or by using the set method.
|
15
|
+
- Delayed. GoodJob will run the job in the future through perform_later.
|
16
|
+
- Priorities. The order in which jobs are processed can be configured differently.
|
17
|
+
- Timeouts. GoodJob defers to ActiveJob where it can be implemented as an `around` hook. See [Taking advantage of ActiveJob](#taking-advantage-of-activejob).
|
18
|
+
- Retries. GoodJob will automatically retry uncompleted jobs immediately. See [Taking advantage of ActiveJob](#taking-advantage-of-activejob).
|
11
19
|
|
12
20
|
## Installation
|
13
21
|
|
@@ -43,6 +51,9 @@ $ bundle install
|
|
43
51
|
t.integer :priority
|
44
52
|
t.jsonb :serialized_params
|
45
53
|
t.timestamp :scheduled_at
|
54
|
+
|
55
|
+
t.index :scheduled_at
|
56
|
+
t.index [:queue_name, :scheduled_at]
|
46
57
|
end
|
47
58
|
end
|
48
59
|
end
|
@@ -73,6 +84,11 @@ $ bundle install
|
|
73
84
|
config.active_job.queue_adapter = GoodJob::Adapter.new
|
74
85
|
```
|
75
86
|
|
87
|
+
1. Queue your job 🎉:
|
88
|
+
```ruby
|
89
|
+
YourJob.set(queue: :some_queue, wait: 5.minutes, priority: 10).perform_later
|
90
|
+
```
|
91
|
+
|
76
92
|
1. In production, the scheduler is designed to run in its own process:
|
77
93
|
```bash
|
78
94
|
$ bundle exec good_job
|
@@ -90,6 +106,25 @@ $ bundle install
|
|
90
106
|
# [--queues=queue1,queue2] # Queues to work from. Separate multiple queues with commas (default: *)
|
91
107
|
# [--poll-interval=N] # Interval between polls for available jobs in seconds (default: 1)
|
92
108
|
```
|
109
|
+
|
110
|
+
### Taking advantage of ActiveJob
|
111
|
+
|
112
|
+
ActiveJob has a rich set of built-in functionality for timeouts, error handling, and retrying. For example:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class ApplicationJob < ActiveJob::Base
|
116
|
+
# Retry errors an infinite number of times with exponential back-off
|
117
|
+
retry_on StandardError, wait: :exponentially_longer, attempts: Float::INFINITY
|
118
|
+
|
119
|
+
# Timeout jobs after 10 minutes
|
120
|
+
JobTimeoutError = Class.new(StandardError)
|
121
|
+
around_perform do |_job, block|
|
122
|
+
Timeout.timeout(10.minutes, JobTimeoutError) do
|
123
|
+
block.call
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
```
|
93
128
|
|
94
129
|
### Configuring Job Execution Threads
|
95
130
|
|
data/lib/good_job/adapter.rb
CHANGED
@@ -11,7 +11,7 @@ module GoodJob
|
|
11
11
|
def enqueue_at(active_job, timestamp)
|
12
12
|
good_job = GoodJob::Job.enqueue(
|
13
13
|
active_job,
|
14
|
-
scheduled_at: timestamp ? Time.at(timestamp) : nil,
|
14
|
+
scheduled_at: timestamp ? Time.zone.at(timestamp) : nil,
|
15
15
|
create_with_advisory_lock: inline?
|
16
16
|
)
|
17
17
|
|
data/lib/good_job/job.rb
CHANGED
@@ -2,9 +2,12 @@ module GoodJob
|
|
2
2
|
class Job < ActiveRecord::Base
|
3
3
|
include Lockable
|
4
4
|
|
5
|
-
|
5
|
+
DEFAULT_QUEUE_NAME = 'default'.freeze
|
6
|
+
DEFAULT_PRIORITY = 0
|
6
7
|
|
7
|
-
|
8
|
+
self.table_name = 'good_jobs'.freeze
|
9
|
+
|
10
|
+
scope :only_scheduled, -> { where(arel_table['scheduled_at'].lteq(Time.current)).or(where(scheduled_at: nil)) }
|
8
11
|
scope :priority_ordered, -> { order(priority: :desc) }
|
9
12
|
scope :to_performer, -> { Performer.new(self) }
|
10
13
|
|
@@ -31,10 +34,10 @@ module GoodJob
|
|
31
34
|
good_job = nil
|
32
35
|
ActiveSupport::Notifications.instrument("enqueue_job.good_job", { active_job: active_job, scheduled_at: scheduled_at, create_with_advisory_lock: create_with_advisory_lock }) do |instrument_payload|
|
33
36
|
good_job = GoodJob::Job.new(
|
34
|
-
queue_name: active_job.queue_name,
|
35
|
-
priority: active_job.priority,
|
37
|
+
queue_name: active_job.queue_name.presence || DEFAULT_QUEUE_NAME,
|
38
|
+
priority: active_job.priority || DEFAULT_PRIORITY,
|
36
39
|
serialized_params: active_job.serialize,
|
37
|
-
scheduled_at: scheduled_at,
|
40
|
+
scheduled_at: scheduled_at || Time.current,
|
38
41
|
create_with_advisory_lock: create_with_advisory_lock
|
39
42
|
)
|
40
43
|
|
data/lib/good_job/lockable.rb
CHANGED
@@ -37,14 +37,17 @@ module GoodJob
|
|
37
37
|
scope :owns_advisory_locked, -> { joins_advisory_locks.where('"pg_locks"."pid" = pg_backend_pid()') }
|
38
38
|
|
39
39
|
attr_accessor :create_with_advisory_lock
|
40
|
+
|
40
41
|
after_create -> { advisory_lock }, if: :create_with_advisory_lock
|
41
42
|
end
|
42
43
|
|
43
44
|
class_methods do
|
44
|
-
def with_advisory_lock
|
45
|
+
def with_advisory_lock
|
46
|
+
raise ArgumentError, "Must provide a block" unless block_given?
|
47
|
+
|
45
48
|
records = advisory_lock.to_a
|
46
49
|
begin
|
47
|
-
|
50
|
+
yield(records)
|
48
51
|
ensure
|
49
52
|
records.each(&:advisory_unlock)
|
50
53
|
end
|
@@ -73,6 +76,8 @@ module GoodJob
|
|
73
76
|
end
|
74
77
|
|
75
78
|
def with_advisory_lock
|
79
|
+
raise ArgumentError, "Must provide a block" unless block_given?
|
80
|
+
|
76
81
|
advisory_lock!
|
77
82
|
yield
|
78
83
|
ensure
|
data/lib/good_job/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: good_job
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Sheldon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -178,6 +178,34 @@ dependencies:
|
|
178
178
|
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rubocop-performance
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: rubocop-rails
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
181
209
|
- !ruby/object:Gem::Dependency
|
182
210
|
name: rubocop-rspec
|
183
211
|
requirement: !ruby/object:Gem::Requirement
|