good_job 0.2.2 → 0.3.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 +6 -2
- data/README.md +11 -0
- data/lib/good_job.rb +1 -2
- data/lib/good_job/adapter.rb +16 -21
- data/lib/good_job/cli.rb +8 -3
- data/lib/good_job/job.rb +33 -0
- data/lib/good_job/lockable.rb +58 -67
- data/lib/good_job/pg_locks.rb +21 -0
- data/lib/good_job/scheduler.rb +20 -27
- data/lib/good_job/version.rb +1 -1
- metadata +18 -5
- data/lib/good_job/inline_scheduler.rb +0 -10
- data/lib/good_job/job_wrapper.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fb26ee806945cc3f179365b97150d570d9054c7907a94044f28a2afdd46d389
|
4
|
+
data.tar.gz: ab7d3247d78ad394e729c4b4787157ea3b60b0eeb01d0a31a2c93694a3320a62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8065515ccdf0533d6069688a2afba7ffdb71a2ba9ad45660fda62b3c6c8347eff8e7d6a0a735bfcd974176a1e1e2e1168efd5dc74aa6fbe155326cb33f7700c3
|
7
|
+
data.tar.gz: 6e8877daa20867a5748b62a3e40130ee8a270c9c2db3ba1a8a460c76d33b9a48e6d8f127e779fe0808d245cc75276d36492adf7e70850640e729adbe2863e715
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## [0.
|
3
|
+
## [0.3.0](https://github.com/bensheldon/good_job/tree/0.3.0) (2020-03-22)
|
4
4
|
|
5
|
-
[Full Changelog](https://github.com/bensheldon/good_job/compare/v0.2.1...0.
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v0.2.1...0.3.0)
|
6
6
|
|
7
7
|
**Merged pull requests:**
|
8
8
|
|
9
|
+
- Update development Ruby to 2.6.5 [\#22](https://github.com/bensheldon/good_job/pull/22) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
- Simplify the internal API, removing JobWrapper and InlineScheduler [\#21](https://github.com/bensheldon/good_job/pull/21) ([bensheldon](https://github.com/bensheldon))
|
11
|
+
- Generate a new future for every executed job [\#20](https://github.com/bensheldon/good_job/pull/20) ([bensheldon](https://github.com/bensheldon))
|
12
|
+
- Configuration for maximum number of job execution threads [\#18](https://github.com/bensheldon/good_job/pull/18) ([bensheldon](https://github.com/bensheldon))
|
9
13
|
- Gracefully shutdown Scheduler when executable receives TERM or INT [\#17](https://github.com/bensheldon/good_job/pull/17) ([bensheldon](https://github.com/bensheldon))
|
10
14
|
- Update Appraisals [\#16](https://github.com/bensheldon/good_job/pull/16) ([bensheldon](https://github.com/bensheldon))
|
11
15
|
|
data/README.md
CHANGED
@@ -67,6 +67,17 @@ $ bundle
|
|
67
67
|
```bash
|
68
68
|
$ bundle exec good_job
|
69
69
|
```
|
70
|
+
|
71
|
+
### Configuring Job Execution Threads
|
72
|
+
|
73
|
+
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:
|
74
|
+
|
75
|
+
- Each GoodJob execution thread requires its own database connection, which are automatically checked out from Rails’s connection pool. _Allowing GoodJob to schedule more threads than are available in the database connection pool can lead to timeouts and is not recommended._
|
76
|
+
- The maximum number of GoodJob threads can be configured, in decreasing precedence:
|
77
|
+
1. `$ bundle exec good_job --max_threads 4`
|
78
|
+
2. `$ GOOD_JOB_MAX_THREADS=4 bundle exec good_job`
|
79
|
+
3. `$ RAILS_MAX_THREADS=4 bundle exec good_job`
|
80
|
+
4. Implicitly via Rails's database connection pool size (`ActiveRecord::Base.connection_pool.size`)
|
70
81
|
|
71
82
|
## Development
|
72
83
|
|
data/lib/good_job.rb
CHANGED
@@ -4,10 +4,9 @@ require 'good_job/railtie'
|
|
4
4
|
require 'good_job/logging'
|
5
5
|
require 'good_job/lockable'
|
6
6
|
require 'good_job/job'
|
7
|
-
require 'good_job/inline_scheduler'
|
8
7
|
require "good_job/scheduler"
|
9
|
-
require "good_job/job_wrapper"
|
10
8
|
require 'good_job/adapter'
|
9
|
+
require 'good_job/pg_locks'
|
11
10
|
|
12
11
|
module GoodJob
|
13
12
|
include Logging
|
data/lib/good_job/adapter.rb
CHANGED
@@ -1,41 +1,36 @@
|
|
1
1
|
module GoodJob
|
2
2
|
class Adapter
|
3
|
-
def initialize(
|
4
|
-
@
|
5
|
-
@scheduler = InlineScheduler.new if inline?
|
3
|
+
def initialize(inline: false)
|
4
|
+
@inline = inline
|
6
5
|
end
|
7
6
|
|
8
|
-
def enqueue(
|
9
|
-
enqueue_at(
|
7
|
+
def enqueue(active_job)
|
8
|
+
enqueue_at(active_job, nil)
|
10
9
|
end
|
11
10
|
|
12
|
-
def enqueue_at(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
params[:scheduled_at] = Time.at(timestamp) if timestamp
|
11
|
+
def enqueue_at(active_job, timestamp)
|
12
|
+
good_job = GoodJob::Job.enqueue(
|
13
|
+
active_job,
|
14
|
+
scheduled_at: timestamp ? Time.at(timestamp) : nil,
|
15
|
+
create_with_advisory_lock: inline?
|
16
|
+
)
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
GoodJob.tag_logger do
|
24
|
-
ActiveSupport::Notifications.instrument("create.good_job", { good_job: good_job, job: job })
|
25
|
-
@scheduler.enqueue(good_job) if inline?
|
18
|
+
if inline?
|
19
|
+
good_job.perform
|
20
|
+
good_job.advisory_unlock
|
26
21
|
end
|
27
22
|
|
28
23
|
good_job
|
29
24
|
end
|
30
25
|
|
31
|
-
def shutdown(wait: true)
|
32
|
-
|
26
|
+
def shutdown(wait: true) # rubocop:disable Lint/UnusedMethodArgument
|
27
|
+
nil
|
33
28
|
end
|
34
29
|
|
35
30
|
private
|
36
31
|
|
37
32
|
def inline?
|
38
|
-
@
|
33
|
+
@inline
|
39
34
|
end
|
40
35
|
end
|
41
36
|
end
|
data/lib/good_job/cli.rb
CHANGED
@@ -5,18 +5,23 @@ module GoodJob
|
|
5
5
|
RAILS_ENVIRONMENT_RB = File.expand_path("config/environment.rb")
|
6
6
|
|
7
7
|
desc :start, "Start jobs"
|
8
|
+
method_option :max_threads, type: :numeric
|
8
9
|
def start
|
9
10
|
require RAILS_ENVIRONMENT_RB
|
10
11
|
|
11
|
-
|
12
|
+
max_threads = options[:max_threads] ||
|
13
|
+
ENV['GOOD_JOB_MAX_THREADS'] ||
|
14
|
+
ENV['RAILS_MAX_THREADS'] ||
|
15
|
+
ActiveRecord::Base.connection_pool.size
|
16
|
+
|
17
|
+
$stdout.puts "GoodJob starting with max_threads=#{max_threads}"
|
18
|
+
scheduler = GoodJob::Scheduler.new(pool_options: { max_threads: max_threads })
|
12
19
|
|
13
20
|
%w[INT TERM].each do |signal|
|
14
21
|
trap(signal) { @stop_good_job_executable = true }
|
15
22
|
end
|
16
23
|
@stop_good_job_executable = false
|
17
24
|
|
18
|
-
$stdout.puts "GoodJob waiting for jobs..."
|
19
|
-
|
20
25
|
Kernel.loop do
|
21
26
|
sleep 0.1
|
22
27
|
break if @stop_good_job_executable || scheduler.shutdown?
|
data/lib/good_job/job.rb
CHANGED
@@ -1,6 +1,39 @@
|
|
1
1
|
module GoodJob
|
2
2
|
class Job < ActiveRecord::Base
|
3
3
|
include Lockable
|
4
|
+
|
4
5
|
self.table_name = 'good_jobs'
|
6
|
+
|
7
|
+
def self.enqueue(active_job, scheduled_at: nil, create_with_advisory_lock: false)
|
8
|
+
good_job = nil
|
9
|
+
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|
|
10
|
+
good_job = GoodJob::Job.new(
|
11
|
+
queue_name: active_job.queue_name,
|
12
|
+
priority: active_job.priority,
|
13
|
+
serialized_params: active_job.serialize,
|
14
|
+
scheduled_at: scheduled_at,
|
15
|
+
create_with_advisory_lock: create_with_advisory_lock
|
16
|
+
)
|
17
|
+
|
18
|
+
instrument_payload[:good_job] = good_job
|
19
|
+
|
20
|
+
good_job.save!
|
21
|
+
active_job.provider_job_id = good_job.id
|
22
|
+
end
|
23
|
+
|
24
|
+
good_job
|
25
|
+
end
|
26
|
+
|
27
|
+
def perform
|
28
|
+
ActiveSupport::Notifications.instrument("before_perform_job.good_job", { good_job: self })
|
29
|
+
ActiveSupport::Notifications.instrument("perform_job.good_job", { good_job: self }) do
|
30
|
+
params = serialized_params.merge(
|
31
|
+
"provider_job_id" => id
|
32
|
+
)
|
33
|
+
ActiveJob::Base.execute(params)
|
34
|
+
|
35
|
+
destroy!
|
36
|
+
end
|
37
|
+
end
|
5
38
|
end
|
6
39
|
end
|
data/lib/good_job/lockable.rb
CHANGED
@@ -15,88 +15,79 @@ module GoodJob
|
|
15
15
|
end)
|
16
16
|
|
17
17
|
scope :advisory_unlocked, -> { joins_advisory_locks.where(pg_locks: { locktype: nil }) }
|
18
|
-
scope :with_advisory_lock, (lambda do
|
19
|
-
where(<<~SQL)
|
20
|
-
pg_try_advisory_lock(('x'||substr(md5(id::text), 1, 16))::bit(64)::bigint)
|
21
|
-
SQL
|
22
|
-
end)
|
23
18
|
|
24
|
-
|
25
|
-
|
19
|
+
attr_accessor :create_with_advisory_lock
|
20
|
+
|
21
|
+
after_create -> { advisory_lock }, if: :create_with_advisory_lock
|
22
|
+
end
|
23
|
+
|
24
|
+
class_methods do
|
25
|
+
def first_advisory_locked_row(query)
|
26
|
+
find_by_sql(<<~SQL).first
|
26
27
|
WITH rows AS (#{query.to_sql})
|
27
|
-
SELECT rows
|
28
|
+
SELECT rows.*
|
28
29
|
FROM rows
|
29
30
|
WHERE pg_try_advisory_lock(('x'||substr(md5(id::text), 1, 16))::bit(64)::bigint)
|
31
|
+
LIMIT 1
|
30
32
|
SQL
|
31
33
|
end
|
32
|
-
|
33
|
-
|
34
|
-
# https://www.postgresql.org/docs/9.6/view-pg-locks.html
|
35
|
-
# Advisory locks can be acquired on keys consisting of either a single bigint value or two integer values.
|
36
|
-
# A bigint key is displayed with its high-order half in the classid column, its low-order half in the objid column, and objsubid equal to 1.
|
37
|
-
# The original bigint value can be reassembled with the expression (classid::bigint << 32) | objid::bigint.
|
38
|
-
# Integer keys are displayed with the first key in the classid column, the second key in the objid column, and objsubid equal to 2.
|
39
|
-
# The actual meaning of the keys is up to the user. Advisory locks are local to each database, so the database column is meaningful for an advisory lock.
|
40
|
-
def self.advisory_lock_details
|
41
|
-
connection.select("SELECT * FROM pg_locks WHERE locktype = 'advisory' AND objsubid = 1")
|
42
|
-
end
|
34
|
+
end
|
43
35
|
|
44
|
-
|
45
|
-
|
46
|
-
|
36
|
+
def advisory_lock
|
37
|
+
self.class.connection.execute(sanitize_sql_for_conditions(["SELECT 1 as one WHERE pg_try_advisory_lock(('x'||substr(md5(?), 1, 16))::bit(64)::bigint)", id])).ntuples.positive?
|
38
|
+
end
|
47
39
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
40
|
+
def advisory_lock!
|
41
|
+
result = advisory_lock
|
42
|
+
result || raise(RecordAlreadyAdvisoryLockedError)
|
43
|
+
end
|
52
44
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
45
|
+
def with_advisory_lock
|
46
|
+
advisory_lock!
|
47
|
+
yield
|
48
|
+
rescue StandardError => e
|
49
|
+
advisory_unlock unless e.is_a? RecordAlreadyAdvisoryLockedError
|
50
|
+
raise
|
51
|
+
end
|
60
52
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
53
|
+
def advisory_locked?
|
54
|
+
self.class.connection.execute(<<~SQL).ntuples.positive?
|
55
|
+
SELECT 1 as one
|
56
|
+
FROM pg_locks
|
57
|
+
WHERE
|
58
|
+
locktype = 'advisory'
|
59
|
+
AND objsubid = 1
|
60
|
+
AND classid = ('x'||substr(md5('#{id}'), 1, 16))::bit(32)::int
|
61
|
+
AND objid = (('x'||substr(md5('#{id}'), 1, 16))::bit(64) << 32)::bit(32)::int
|
62
|
+
SQL
|
63
|
+
end
|
72
64
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
65
|
+
def owns_advisory_lock?
|
66
|
+
self.class.connection.execute(<<~SQL).ntuples.positive?
|
67
|
+
SELECT 1 as one
|
68
|
+
FROM pg_locks
|
69
|
+
WHERE
|
70
|
+
locktype = 'advisory'
|
71
|
+
AND objsubid = 1
|
72
|
+
AND classid = ('x'||substr(md5('#{id}'), 1, 16))::bit(32)::int
|
73
|
+
AND objid = (('x'||substr(md5('#{id}'), 1, 16))::bit(64) << 32)::bit(32)::int
|
74
|
+
AND pid = pg_backend_pid()
|
75
|
+
SQL
|
76
|
+
end
|
85
77
|
|
86
|
-
|
87
|
-
|
88
|
-
|
78
|
+
def advisory_unlock
|
79
|
+
self.class.connection.execute("SELECT pg_advisory_unlock(('x'||substr(md5('#{id}'), 1, 16))::bit(64)::bigint)").first["pg_advisory_unlock"]
|
80
|
+
end
|
89
81
|
|
90
|
-
|
91
|
-
|
92
|
-
|
82
|
+
def advisory_unlock!
|
83
|
+
advisory_unlock while advisory_locked?
|
84
|
+
end
|
93
85
|
|
94
|
-
|
86
|
+
private
|
95
87
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
88
|
+
def sanitize_sql_for_conditions(*args)
|
89
|
+
# Made public in Rails 5.2
|
90
|
+
self.class.send(:sanitize_sql_for_conditions, *args)
|
100
91
|
end
|
101
92
|
end
|
102
93
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GoodJob
|
2
|
+
class PgLocks < ActiveRecord::Base
|
3
|
+
self.table_name = 'pg_locks'.freeze
|
4
|
+
|
5
|
+
# https://www.postgresql.org/docs/9.6/view-pg-locks.html
|
6
|
+
# Advisory locks can be acquired on keys consisting of either a single bigint value or two integer values.
|
7
|
+
# A bigint key is displayed with its high-order half in the classid column, its low-order half in the objid column, and objsubid equal to 1.
|
8
|
+
# The original bigint value can be reassembled with the expression (classid::bigint << 32) | objid::bigint.
|
9
|
+
# Integer keys are displayed with the first key in the classid column, the second key in the objid column, and objsubid equal to 2.
|
10
|
+
# The actual meaning of the keys is up to the user. Advisory locks are local to each database, so the database column is meaningful for an advisory lock.
|
11
|
+
def self.advisory_lock_details
|
12
|
+
connection.select <<~SQL
|
13
|
+
SELECT *
|
14
|
+
FROM pg_locks
|
15
|
+
WHERE
|
16
|
+
locktype = 'advisory' AND
|
17
|
+
objsubid = 1
|
18
|
+
SQL
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/good_job/scheduler.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
require "concurrent/scheduled_task"
|
2
1
|
require "concurrent/executor/thread_pool_executor"
|
2
|
+
require "concurrent/timer_task"
|
3
3
|
require "concurrent/utility/processor_counter"
|
4
4
|
|
5
5
|
module GoodJob
|
6
6
|
class Scheduler
|
7
|
-
MAX_THREADS = Concurrent.processor_count
|
8
|
-
|
9
7
|
DEFAULT_TIMER_OPTIONS = {
|
10
8
|
execution_interval: 1,
|
11
9
|
timeout_interval: 1,
|
@@ -15,22 +13,22 @@ module GoodJob
|
|
15
13
|
DEFAULT_POOL_OPTIONS = {
|
16
14
|
name: 'good_job',
|
17
15
|
min_threads: 0,
|
18
|
-
max_threads:
|
16
|
+
max_threads: Concurrent.processor_count,
|
19
17
|
auto_terminate: true,
|
20
18
|
idletime: 0,
|
21
19
|
max_queue: 0,
|
22
20
|
fallback_policy: :abort, # shouldn't matter -- 0 max queue
|
23
21
|
}.freeze
|
24
22
|
|
25
|
-
def initialize(query = GoodJob::Job.all,
|
23
|
+
def initialize(query = GoodJob::Job.all, timer_options: {}, pool_options: {})
|
26
24
|
@query = query
|
27
25
|
|
28
|
-
@pool = Concurrent::ThreadPoolExecutor.new(DEFAULT_POOL_OPTIONS)
|
29
|
-
@timer = Concurrent::TimerTask.new(DEFAULT_TIMER_OPTIONS) do
|
26
|
+
@pool = Concurrent::ThreadPoolExecutor.new(DEFAULT_POOL_OPTIONS.merge(pool_options))
|
27
|
+
@timer = Concurrent::TimerTask.new(DEFAULT_TIMER_OPTIONS.merge(timer_options)) do
|
30
28
|
idle_threads = @pool.max_length - @pool.length
|
31
29
|
create_thread if idle_threads.positive?
|
32
30
|
end
|
33
|
-
@timer.add_observer(
|
31
|
+
@timer.add_observer(self, :timer_observer)
|
34
32
|
@timer.execute
|
35
33
|
end
|
36
34
|
|
@@ -64,35 +62,30 @@ module GoodJob
|
|
64
62
|
|
65
63
|
def create_thread
|
66
64
|
future = Concurrent::Future.new(args: [ordered_query], executor: @pool) do |query|
|
67
|
-
|
68
|
-
loop do
|
69
|
-
good_job = query.with_advisory_lock.first
|
70
|
-
break unless good_job
|
71
|
-
|
72
|
-
ActiveSupport::Notifications.instrument("job_started.good_job", { good_job: good_job })
|
65
|
+
executed_job = false
|
73
66
|
|
74
|
-
|
67
|
+
Rails.application.executor.wrap do
|
68
|
+
good_job = GoodJob::Job.first_advisory_locked_row(query)
|
69
|
+
break unless good_job
|
75
70
|
|
76
|
-
|
77
|
-
|
71
|
+
executed_job = true
|
72
|
+
good_job.perform
|
73
|
+
good_job.advisory_unlock
|
78
74
|
end
|
79
75
|
|
80
|
-
|
76
|
+
executed_job
|
81
77
|
end
|
82
|
-
future.add_observer(
|
78
|
+
future.add_observer(self, :task_observer)
|
83
79
|
future.execute
|
84
80
|
end
|
85
81
|
|
86
|
-
|
87
|
-
|
88
|
-
ActiveSupport::Notifications.instrument("timer_task_finished.good_job", { result: result, error: error, time: time })
|
89
|
-
end
|
82
|
+
def timer_observer(time, executed_task, error)
|
83
|
+
ActiveSupport::Notifications.instrument("finished_timer_task.good_job", { result: executed_task, error: error, time: time })
|
90
84
|
end
|
91
85
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
86
|
+
def task_observer(time, executed_task, error)
|
87
|
+
ActiveSupport::Notifications.instrument("finished_job_task.good_job", { result: executed_task, error: error, time: time })
|
88
|
+
create_thread if executed_task
|
96
89
|
end
|
97
90
|
end
|
98
91
|
end
|
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.3.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-03-
|
11
|
+
date: 2020-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: rspec-rails
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,11 +196,10 @@ files:
|
|
182
196
|
- lib/good_job.rb
|
183
197
|
- lib/good_job/adapter.rb
|
184
198
|
- lib/good_job/cli.rb
|
185
|
-
- lib/good_job/inline_scheduler.rb
|
186
199
|
- lib/good_job/job.rb
|
187
|
-
- lib/good_job/job_wrapper.rb
|
188
200
|
- lib/good_job/lockable.rb
|
189
201
|
- lib/good_job/logging.rb
|
202
|
+
- lib/good_job/pg_locks.rb
|
190
203
|
- lib/good_job/railtie.rb
|
191
204
|
- lib/good_job/scheduler.rb
|
192
205
|
- lib/good_job/version.rb
|
@@ -221,7 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
221
234
|
- !ruby/object:Gem::Version
|
222
235
|
version: '0'
|
223
236
|
requirements: []
|
224
|
-
rubygems_version: 3.
|
237
|
+
rubygems_version: 3.0.3
|
225
238
|
signing_key:
|
226
239
|
specification_version: 4
|
227
240
|
summary: A multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
|
data/lib/good_job/job_wrapper.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module GoodJob
|
2
|
-
class JobWrapper
|
3
|
-
def initialize(good_job)
|
4
|
-
@good_job = good_job
|
5
|
-
end
|
6
|
-
|
7
|
-
def perform
|
8
|
-
serialized_params = @good_job.serialized_params.merge(
|
9
|
-
"provider_job_id" => @good_job.id
|
10
|
-
)
|
11
|
-
ActiveJob::Base.execute(serialized_params)
|
12
|
-
|
13
|
-
@good_job.destroy!
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|