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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c20439024a46084c22e46bb42e38589687c2ab2cea47d90705abc4fa042ad449
4
- data.tar.gz: e5ea8e7fa607a10fd936c62623a39d32b891ef629636e0b04fb3d36aa7ab1f3f
3
+ metadata.gz: 4f7dda29494df3fc05a199d6bf0efbc825a47653c3af507a0d1ceb92456d4307
4
+ data.tar.gz: 881ad046bab6b17c5d532d035fddef54420639288a0a4bd8f4f07b980c1fa239
5
5
  SHA512:
6
- metadata.gz: 4af34ce400c409a61892c9d35693f69e023b5dbd3d54cacfd6d9b044aaf481c616e3fdb9da53470f79919830a916a08f67550ce807eda1c59a43fa1da4092f07
7
- data.tar.gz: 81304be6bc9e6925b16fa030d2031377bd90bac894b4c8792cfe5e02ff81677bf04d476b1a3435e951a804e6d284e4d8aa7452c6090969f841dbd6e59a9c301c
6
+ metadata.gz: c0cfc3c4d61666844a6bd7c532670e0b1be40fd6f805eff63919d3600d06933b8029f0febbc81efbf52b1f3d459317caeb522affe20dde9d3f4d7672622fd708
7
+ data.tar.gz: c4c9a9fddb2108769e3672baeaeaca2f7c966ee708f95867ed57970e688debcf1ce41a3eacd65d88c0192700f1b293cd4a9ad63fee9e4af93d44934b0876120f
@@ -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
 
@@ -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
 
@@ -2,9 +2,12 @@ module GoodJob
2
2
  class Job < ActiveRecord::Base
3
3
  include Lockable
4
4
 
5
- self.table_name = 'good_jobs'
5
+ DEFAULT_QUEUE_NAME = 'default'.freeze
6
+ DEFAULT_PRIORITY = 0
6
7
 
7
- scope :only_scheduled, -> { where("scheduled_at < ?", Time.current).or(where(scheduled_at: nil)) }
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
 
@@ -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(&block)
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
- block.call(records)
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
@@ -1,3 +1,3 @@
1
1
  module GoodJob
2
- VERSION = '0.6.0'.freeze
2
+ VERSION = '0.7.0'.freeze
3
3
  end
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.6.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-15 00:00:00.000000000 Z
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