good_job 2.99.0 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,224 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
- # ActiveRecord model that represents an +ActiveJob+ job.
4
- # There is not a table in the database whose discrete rows represents "Jobs".
5
- # The +good_jobs+ table is a table of individual {GoodJob::Execution}s that share the same +active_job_id+.
6
- # A single row from the +good_jobs+ table of executions is fetched to represent an ActiveJobJob
7
- class ActiveJobJob < BaseRecord
8
- include Filterable
9
- include Lockable
10
-
11
- # Raised when an inappropriate action is applied to a Job based on its state.
12
- ActionForStateMismatchError = Class.new(StandardError)
13
- # Raised when an action requires GoodJob to be the ActiveJob Queue Adapter but GoodJob is not.
14
- AdapterNotGoodJobError = Class.new(StandardError)
15
- # Attached to a Job's Execution when the Job is discarded.
16
- DiscardJobError = Class.new(StandardError)
17
-
18
- class << self
19
- delegate :table_name, to: GoodJob::Execution
20
-
21
- def table_name=(_value)
22
- raise NotImplementedError, 'Assign GoodJob::Execution.table_name directly'
23
- end
24
- end
25
-
26
- self.primary_key = 'active_job_id'
27
- self.advisory_lockable_column = 'active_job_id'
28
-
29
- has_many :executions, -> { order(created_at: :asc) }, class_name: 'GoodJob::Execution', foreign_key: 'active_job_id', inverse_of: :job
30
-
31
- # Only the most-recent unretried execution represents a "Job"
32
- default_scope { where(retried_good_job_id: nil) }
33
-
34
- # Get Jobs with given class name
35
- # @!method job_class
36
- # @!scope class
37
- # @param string [String] Execution class name
38
- # @return [ActiveRecord::Relation]
39
- scope :job_class, ->(job_class) { where("serialized_params->>'job_class' = ?", job_class) }
40
-
41
- # Get Jobs finished before the given timestamp.
42
- # @!method finished_before(timestamp)
43
- # @!scope class
44
- # @param timestamp (DateTime, Time)
45
- # @return [ActiveRecord::Relation]
46
- scope :finished_before, ->(timestamp) { where(arel_table['finished_at'].lteq(timestamp)) }
47
-
48
- # First execution will run in the future
49
- scope :scheduled, -> { where(finished_at: nil).where('COALESCE(scheduled_at, created_at) > ?', DateTime.current).where("(serialized_params->>'executions')::integer < 2") }
50
- # Execution errored, will run in the future
51
- scope :retried, -> { where(finished_at: nil).where('COALESCE(scheduled_at, created_at) > ?', DateTime.current).where("(serialized_params->>'executions')::integer > 1") }
52
- # Immediate/Scheduled time to run has passed, waiting for an available thread run
53
- scope :queued, -> { where(finished_at: nil).where('COALESCE(scheduled_at, created_at) <= ?', DateTime.current).joins_advisory_locks.where(pg_locks: { locktype: nil }) }
54
- # Advisory locked and executing
55
- scope :running, -> { where(finished_at: nil).joins_advisory_locks.where.not(pg_locks: { locktype: nil }) }
56
- # Completed executing successfully
57
- scope :finished, -> { not_discarded.where.not(finished_at: nil) }
58
- # Errored but will not be retried
59
- scope :discarded, -> { where.not(finished_at: nil).where.not(error: nil) }
60
- # Not errored
61
- scope :not_discarded, -> { where(error: nil) }
62
-
63
- # The job's ActiveJob UUID
64
- # @return [String]
65
- def id
66
- active_job_id
67
- end
68
-
69
- # The ActiveJob job class, as a string
70
- # @return [String]
71
- def job_class
72
- serialized_params['job_class']
73
- end
74
-
75
- # The status of the Job, based on the state of its most recent execution.
76
- # @return [Symbol]
77
- delegate :status, :last_status_at, to: :head_execution
78
-
79
- # This job's most recent {Execution}
80
- # @param reload [Booelan] whether to reload executions
81
- # @return [Execution]
82
- def head_execution(reload: false)
83
- executions.reload if reload
84
- executions.load # memoize the results
85
- executions.last
86
- end
87
-
88
- # This job's initial/oldest {Execution}
89
- # @return [Execution]
90
- def tail_execution
91
- executions.first
92
- end
93
-
94
- # The number of times this job has been executed, according to ActiveJob's serialized state.
95
- # @return [Numeric]
96
- def executions_count
97
- aj_count = head_execution.serialized_params.fetch('executions', 0)
98
- # The execution count within serialized_params is not updated
99
- # once the underlying execution has been executed.
100
- if status.in? [:discarded, :finished, :running]
101
- aj_count + 1
102
- else
103
- aj_count
104
- end
105
- end
106
-
107
- # The number of times this job has been executed, according to the number of GoodJob {Execution} records.
108
- # @return [Numeric]
109
- def preserved_executions_count
110
- executions.size
111
- end
112
-
113
- # The most recent error message.
114
- # If the job has been retried, the error will be fetched from the previous {Execution} record.
115
- # @return [String]
116
- def recent_error
117
- head_execution.error || executions[-2]&.error
118
- end
119
-
120
- # Tests whether the job is being executed right now.
121
- # @return [Boolean]
122
- def running?
123
- # Avoid N+1 Query: `.includes_advisory_locks`
124
- if has_attribute?(:locktype)
125
- self['locktype'].present?
126
- else
127
- advisory_locked?
128
- end
129
- end
130
-
131
- # Retry a job that has errored and been discarded.
132
- # This action will create a new {Execution} record for the job.
133
- # @return [ActiveJob::Base]
134
- def retry_job
135
- with_advisory_lock do
136
- execution = head_execution(reload: true)
137
- active_job = execution.active_job
138
-
139
- raise AdapterNotGoodJobError unless active_job.class.queue_adapter.is_a? GoodJob::Adapter
140
- raise ActionForStateMismatchError if execution.finished_at.blank? || execution.error.blank?
141
-
142
- # Update the executions count because the previous execution will not have been preserved
143
- # Do not update `exception_executions` because that comes from rescue_from's arguments
144
- active_job.executions = (active_job.executions || 0) + 1
145
-
146
- new_active_job = nil
147
- GoodJob::CurrentThread.within do |current_thread|
148
- current_thread.execution = execution
149
-
150
- execution.class.transaction(joinable: false, requires_new: true) do
151
- new_active_job = active_job.retry_job(wait: 0, error: execution.error)
152
- execution.save
153
- end
154
- end
155
- new_active_job
156
- end
157
- end
158
-
159
- # Discard a job so that it will not be executed further.
160
- # This action will add a {DiscardJobError} to the job's {Execution} and mark it as finished.
161
- # @return [void]
162
- def discard_job(message)
163
- with_advisory_lock do
164
- execution = head_execution(reload: true)
165
- active_job = execution.active_job
166
-
167
- raise ActionForStateMismatchError if execution.finished_at.present?
168
-
169
- job_error = GoodJob::ActiveJobJob::DiscardJobError.new(message)
170
-
171
- update_execution = proc do
172
- execution.update(
173
- finished_at: Time.current,
174
- error: [job_error.class, GoodJob::Execution::ERROR_MESSAGE_SEPARATOR, job_error.message].join
175
- )
176
- end
177
-
178
- if active_job.respond_to?(:instrument)
179
- active_job.send :instrument, :discard, error: job_error, &update_execution
180
- else
181
- update_execution.call
182
- end
183
- end
184
- end
185
-
186
- # Reschedule a scheduled job so that it executes immediately (or later) by the next available execution thread.
187
- # @param scheduled_at [DateTime, Time] When to reschedule the job
188
- # @return [void]
189
- def reschedule_job(scheduled_at = Time.current)
190
- with_advisory_lock do
191
- execution = head_execution(reload: true)
192
-
193
- raise ActionForStateMismatchError if execution.finished_at.present?
194
-
195
- execution = head_execution(reload: true)
196
- execution.update(scheduled_at: scheduled_at)
197
- end
198
- end
199
-
200
- # Destroy all of a discarded or finished job's executions from the database so that it will no longer appear on the dashboard.
201
- # @return [void]
202
- def destroy_job
203
- with_advisory_lock do
204
- execution = head_execution(reload: true)
205
-
206
- raise ActionForStateMismatchError if execution.finished_at.blank?
207
-
208
- destroy
209
- end
210
- end
211
-
212
- # Utility method to determine which execution record is used to represent this job
213
- # @return [String]
214
- def _execution_id
215
- attributes['id']
216
- end
217
-
218
- # Utility method to test whether this job's underlying attributes represents its most recent execution.
219
- # @return [Boolean]
220
- def _head?
221
- _execution_id == head_execution(reload: true).id
3
+ # @deprecated Use {GoodJob::Job} instead.
4
+ class ActiveJobJob < Execution
5
+ after_initialize do |_job|
6
+ ActiveSupport::Deprecation.warn(
7
+ "The `GoodJob::ActiveJobJob` class name is deprecated. Replace with `GoodJob::Job`."
8
+ )
222
9
  end
223
10
  end
224
11
  end
@@ -73,13 +73,13 @@ module GoodJob # :nodoc:
73
73
  end
74
74
 
75
75
  def jobs
76
- GoodJob::ActiveJobJob.where(cron_key: key)
76
+ GoodJob::Job.where(cron_key: key)
77
77
  end
78
78
 
79
79
  def last_at
80
80
  return if last_job.blank?
81
81
 
82
- if GoodJob::ActiveJobJob.column_names.include?('cron_at')
82
+ if GoodJob::Job.column_names.include?('cron_at')
83
83
  (last_job.cron_at || last_job.created_at).localtime
84
84
  else
85
85
  last_job.created_at
@@ -99,7 +99,7 @@ module GoodJob # :nodoc:
99
99
  end
100
100
 
101
101
  def last_job
102
- if GoodJob::ActiveJobJob.column_names.include?('cron_at')
102
+ if GoodJob::Job.column_names.include?('cron_at')
103
103
  jobs.order("cron_at DESC NULLS LAST").first
104
104
  else
105
105
  jobs.order(created_at: :asc).last
@@ -51,7 +51,7 @@ module GoodJob
51
51
  end
52
52
  end
53
53
 
54
- belongs_to :job, class_name: 'GoodJob::ActiveJobJob', foreign_key: 'active_job_id', primary_key: 'active_job_id', optional: true, inverse_of: :executions
54
+ belongs_to :job, class_name: 'GoodJob::Job', foreign_key: 'active_job_id', primary_key: 'active_job_id', optional: true, inverse_of: :executions
55
55
 
56
56
  # Get Jobs with given ActiveJob ID
57
57
  # @!method active_job_id
@@ -207,14 +207,7 @@ module GoodJob
207
207
 
208
208
  if CurrentThread.cron_key
209
209
  execution_args[:cron_key] = CurrentThread.cron_key
210
-
211
- @cron_at_index = column_names.include?('cron_at') && connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at) unless instance_variable_defined?(:@cron_at_index)
212
-
213
- if @cron_at_index
214
- execution_args[:cron_at] = CurrentThread.cron_at
215
- else
216
- migration_pending_warning!
217
- end
210
+ execution_args[:cron_at] = CurrentThread.cron_at
218
211
  elsif CurrentThread.active_job_id && CurrentThread.active_job_id == active_job.job_id
219
212
  execution_args[:cron_key] = CurrentThread.execution.cron_key
220
213
  end
@@ -337,6 +330,7 @@ module GoodJob
337
330
  serialized_params.deep_dup
338
331
  .tap do |job_data|
339
332
  job_data["provider_job_id"] = id
333
+ job_data["good_job_concurrency_key"] = concurrency_key if concurrency_key
340
334
  end
341
335
  end
342
336
 
@@ -346,8 +340,7 @@ module GoodJob
346
340
  current_thread.reset
347
341
  current_thread.execution = self
348
342
 
349
- # DEPRECATION: Remove deprecated `good_job:` parameter in GoodJob v3
350
- ActiveSupport::Notifications.instrument("perform_job.good_job", { good_job: self, execution: self, process_id: current_thread.process_id, thread_name: current_thread.thread_name }) do
343
+ ActiveSupport::Notifications.instrument("perform_job.good_job", { execution: self, process_id: current_thread.process_id, thread_name: current_thread.thread_name }) do
351
344
  value = ActiveJob::Base.execute(active_job_data)
352
345
 
353
346
  if value.is_a?(Exception)
@@ -1,11 +1,224 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
- # @deprecated Use {GoodJob::Execution} instead.
4
- class Job < Execution
5
- after_initialize do |_job|
6
- ActiveSupport::Deprecation.warn(
7
- "The `GoodJob::Job` class name is deprecated. Replace with `GoodJob::Execution`."
8
- )
3
+ # ActiveRecord model that represents an +ActiveJob+ job.
4
+ # There is not a table in the database whose discrete rows represents "Jobs".
5
+ # The +good_jobs+ table is a table of individual {GoodJob::Execution}s that share the same +active_job_id+.
6
+ # A single row from the +good_jobs+ table of executions is fetched to represent an Job
7
+ class Job < BaseRecord
8
+ include Filterable
9
+ include Lockable
10
+
11
+ # Raised when an inappropriate action is applied to a Job based on its state.
12
+ ActionForStateMismatchError = Class.new(StandardError)
13
+ # Raised when an action requires GoodJob to be the ActiveJob Queue Adapter but GoodJob is not.
14
+ AdapterNotGoodJobError = Class.new(StandardError)
15
+ # Attached to a Job's Execution when the Job is discarded.
16
+ DiscardJobError = Class.new(StandardError)
17
+
18
+ class << self
19
+ delegate :table_name, to: GoodJob::Execution
20
+
21
+ def table_name=(_value)
22
+ raise NotImplementedError, 'Assign GoodJob::Execution.table_name directly'
23
+ end
24
+ end
25
+
26
+ self.primary_key = 'active_job_id'
27
+ self.advisory_lockable_column = 'active_job_id'
28
+
29
+ has_many :executions, -> { order(created_at: :asc) }, class_name: 'GoodJob::Execution', foreign_key: 'active_job_id', inverse_of: :job
30
+
31
+ # Only the most-recent unretried execution represents a "Job"
32
+ default_scope { where(retried_good_job_id: nil) }
33
+
34
+ # Get Jobs with given class name
35
+ # @!method job_class
36
+ # @!scope class
37
+ # @param string [String] Execution class name
38
+ # @return [ActiveRecord::Relation]
39
+ scope :job_class, ->(job_class) { where("serialized_params->>'job_class' = ?", job_class) }
40
+
41
+ # Get Jobs finished before the given timestamp.
42
+ # @!method finished_before(timestamp)
43
+ # @!scope class
44
+ # @param timestamp (DateTime, Time)
45
+ # @return [ActiveRecord::Relation]
46
+ scope :finished_before, ->(timestamp) { where(arel_table['finished_at'].lteq(timestamp)) }
47
+
48
+ # First execution will run in the future
49
+ scope :scheduled, -> { where(finished_at: nil).where('COALESCE(scheduled_at, created_at) > ?', DateTime.current).where("(serialized_params->>'executions')::integer < 2") }
50
+ # Execution errored, will run in the future
51
+ scope :retried, -> { where(finished_at: nil).where('COALESCE(scheduled_at, created_at) > ?', DateTime.current).where("(serialized_params->>'executions')::integer > 1") }
52
+ # Immediate/Scheduled time to run has passed, waiting for an available thread run
53
+ scope :queued, -> { where(finished_at: nil).where('COALESCE(scheduled_at, created_at) <= ?', DateTime.current).joins_advisory_locks.where(pg_locks: { locktype: nil }) }
54
+ # Advisory locked and executing
55
+ scope :running, -> { where(finished_at: nil).joins_advisory_locks.where.not(pg_locks: { locktype: nil }) }
56
+ # Completed executing successfully
57
+ scope :finished, -> { not_discarded.where.not(finished_at: nil) }
58
+ # Errored but will not be retried
59
+ scope :discarded, -> { where.not(finished_at: nil).where.not(error: nil) }
60
+ # Not errored
61
+ scope :not_discarded, -> { where(error: nil) }
62
+
63
+ # The job's ActiveJob UUID
64
+ # @return [String]
65
+ def id
66
+ active_job_id
67
+ end
68
+
69
+ # The ActiveJob job class, as a string
70
+ # @return [String]
71
+ def job_class
72
+ serialized_params['job_class']
73
+ end
74
+
75
+ # The status of the Job, based on the state of its most recent execution.
76
+ # @return [Symbol]
77
+ delegate :status, :last_status_at, to: :head_execution
78
+
79
+ # This job's most recent {Execution}
80
+ # @param reload [Booelan] whether to reload executions
81
+ # @return [Execution]
82
+ def head_execution(reload: false)
83
+ executions.reload if reload
84
+ executions.load # memoize the results
85
+ executions.last
86
+ end
87
+
88
+ # This job's initial/oldest {Execution}
89
+ # @return [Execution]
90
+ def tail_execution
91
+ executions.first
92
+ end
93
+
94
+ # The number of times this job has been executed, according to ActiveJob's serialized state.
95
+ # @return [Numeric]
96
+ def executions_count
97
+ aj_count = head_execution.serialized_params.fetch('executions', 0)
98
+ # The execution count within serialized_params is not updated
99
+ # once the underlying execution has been executed.
100
+ if status.in? [:discarded, :finished, :running]
101
+ aj_count + 1
102
+ else
103
+ aj_count
104
+ end
105
+ end
106
+
107
+ # The number of times this job has been executed, according to the number of GoodJob {Execution} records.
108
+ # @return [Numeric]
109
+ def preserved_executions_count
110
+ executions.size
111
+ end
112
+
113
+ # The most recent error message.
114
+ # If the job has been retried, the error will be fetched from the previous {Execution} record.
115
+ # @return [String]
116
+ def recent_error
117
+ head_execution.error || executions[-2]&.error
118
+ end
119
+
120
+ # Tests whether the job is being executed right now.
121
+ # @return [Boolean]
122
+ def running?
123
+ # Avoid N+1 Query: `.includes_advisory_locks`
124
+ if has_attribute?(:locktype)
125
+ self['locktype'].present?
126
+ else
127
+ advisory_locked?
128
+ end
129
+ end
130
+
131
+ # Retry a job that has errored and been discarded.
132
+ # This action will create a new {Execution} record for the job.
133
+ # @return [ActiveJob::Base]
134
+ def retry_job
135
+ with_advisory_lock do
136
+ execution = head_execution(reload: true)
137
+ active_job = execution.active_job
138
+
139
+ raise AdapterNotGoodJobError unless active_job.class.queue_adapter.is_a? GoodJob::Adapter
140
+ raise ActionForStateMismatchError if execution.finished_at.blank? || execution.error.blank?
141
+
142
+ # Update the executions count because the previous execution will not have been preserved
143
+ # Do not update `exception_executions` because that comes from rescue_from's arguments
144
+ active_job.executions = (active_job.executions || 0) + 1
145
+
146
+ new_active_job = nil
147
+ GoodJob::CurrentThread.within do |current_thread|
148
+ current_thread.execution = execution
149
+
150
+ execution.class.transaction(joinable: false, requires_new: true) do
151
+ new_active_job = active_job.retry_job(wait: 0, error: execution.error)
152
+ execution.save
153
+ end
154
+ end
155
+ new_active_job
156
+ end
157
+ end
158
+
159
+ # Discard a job so that it will not be executed further.
160
+ # This action will add a {DiscardJobError} to the job's {Execution} and mark it as finished.
161
+ # @return [void]
162
+ def discard_job(message)
163
+ with_advisory_lock do
164
+ execution = head_execution(reload: true)
165
+ active_job = execution.active_job
166
+
167
+ raise ActionForStateMismatchError if execution.finished_at.present?
168
+
169
+ job_error = GoodJob::Job::DiscardJobError.new(message)
170
+
171
+ update_execution = proc do
172
+ execution.update(
173
+ finished_at: Time.current,
174
+ error: [job_error.class, GoodJob::Execution::ERROR_MESSAGE_SEPARATOR, job_error.message].join
175
+ )
176
+ end
177
+
178
+ if active_job.respond_to?(:instrument)
179
+ active_job.send :instrument, :discard, error: job_error, &update_execution
180
+ else
181
+ update_execution.call
182
+ end
183
+ end
184
+ end
185
+
186
+ # Reschedule a scheduled job so that it executes immediately (or later) by the next available execution thread.
187
+ # @param scheduled_at [DateTime, Time] When to reschedule the job
188
+ # @return [void]
189
+ def reschedule_job(scheduled_at = Time.current)
190
+ with_advisory_lock do
191
+ execution = head_execution(reload: true)
192
+
193
+ raise ActionForStateMismatchError if execution.finished_at.present?
194
+
195
+ execution = head_execution(reload: true)
196
+ execution.update(scheduled_at: scheduled_at)
197
+ end
198
+ end
199
+
200
+ # Destroy all of a discarded or finished job's executions from the database so that it will no longer appear on the dashboard.
201
+ # @return [void]
202
+ def destroy_job
203
+ with_advisory_lock do
204
+ execution = head_execution(reload: true)
205
+
206
+ raise ActionForStateMismatchError if execution.finished_at.blank?
207
+
208
+ destroy
209
+ end
210
+ end
211
+
212
+ # Utility method to determine which execution record is used to represent this job
213
+ # @return [String]
214
+ def _execution_id
215
+ attributes['id']
216
+ end
217
+
218
+ # Utility method to test whether this job's underlying attributes represents its most recent execution.
219
+ # @return [Boolean]
220
+ def _head?
221
+ _execution_id == head_execution(reload: true).id
9
222
  end
10
223
  end
11
224
  end
@@ -25,15 +25,6 @@ module GoodJob # :nodoc:
25
25
  # @return [ActiveRecord::Relation]
26
26
  scope :inactive, -> { advisory_unlocked }
27
27
 
28
- # Whether the +good_job_processes+ table exsists.
29
- # @return [Boolean]
30
- def self.migrated?
31
- return true if connection.table_exists?(table_name)
32
-
33
- migration_pending_warning!
34
- false
35
- end
36
-
37
28
  # UUID that is unique to the current process and changes when forked.
38
29
  # @return [String]
39
30
  def self.current_id
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: 2.99.0
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Sheldon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-26 00:00:00.000000000 Z
11
+ date: 2022-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.2.0
19
+ version: 6.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 5.2.0
26
+ version: 6.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 5.2.0
33
+ version: 6.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 5.2.0
40
+ version: 6.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: concurrent-ruby
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 5.2.0
75
+ version: 6.0.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 5.2.0
82
+ version: 6.0.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: thor
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -414,10 +414,6 @@ files:
414
414
  - lib/generators/good_job/install_generator.rb
415
415
  - lib/generators/good_job/templates/install/migrations/create_good_jobs.rb.erb
416
416
  - lib/generators/good_job/templates/update/migrations/01_create_good_jobs.rb.erb
417
- - lib/generators/good_job/templates/update/migrations/02_add_cron_at_to_good_jobs.rb.erb
418
- - lib/generators/good_job/templates/update/migrations/03_add_cron_key_cron_at_index_to_good_jobs.rb.erb
419
- - lib/generators/good_job/templates/update/migrations/04_create_good_job_processes.rb.erb
420
- - lib/generators/good_job/templates/update/migrations/04_index_good_job_jobs_on_finished_at.rb.erb
421
417
  - lib/generators/good_job/update_generator.rb
422
418
  - lib/good_job.rb
423
419
  - lib/good_job/active_job_extensions.rb
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
- class AddCronAtToGoodJobs < ActiveRecord::Migration<%= migration_version %>
3
- def change
4
- reversible do |dir|
5
- dir.up do
6
- # Ensure this incremental update migration is idempotent
7
- # with monolithic install migration.
8
- return if connection.column_exists?(:good_jobs, :cron_at)
9
- end
10
- end
11
-
12
- add_column :good_jobs, :cron_at, :timestamp
13
- end
14
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
- class AddCronKeyCronAtIndexToGoodJobs < ActiveRecord::Migration<%= migration_version %>
3
- disable_ddl_transaction!
4
-
5
- def change
6
- reversible do |dir|
7
- dir.up do
8
- # Ensure this incremental update migration is idempotent
9
- # with monolithic install migration.
10
- return if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at)
11
- end
12
- end
13
-
14
- add_index :good_jobs,
15
- [:cron_key, :cron_at],
16
- algorithm: :concurrently,
17
- name: :index_good_jobs_on_cron_key_and_cron_at,
18
- unique: true
19
- end
20
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
- class CreateGoodJobProcesses < ActiveRecord::Migration<%= migration_version %>
3
- def change
4
- reversible do |dir|
5
- dir.up do
6
- # Ensure this incremental update migration is idempotent
7
- # with monolithic install migration.
8
- return if connection.table_exists?(:good_job_processes)
9
- end
10
- end
11
-
12
- create_table :good_job_processes, id: :uuid do |t|
13
- t.timestamps
14
- t.jsonb :state
15
- end
16
- end
17
- end