ae_active_job_state 0.1.0 → 1.0.1

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: 06a4c9233311e99e2aa3f14bcf7310c36ab0221ed9fe8cd01d0c9b660c9cd6f1
4
- data.tar.gz: 4d15d5d24db0a18f773a05695e6139d3acfdbabdbdee91080b218e0eb31d00e1
3
+ metadata.gz: 438d235a0e744da0dbddf380bb9faeb2b53806b63f86b9a2097821ab3fc7d54a
4
+ data.tar.gz: 643996efa46db8ac41d16eb23968cee40647ec049fc3a852d2c2387ca7bc1693
5
5
  SHA512:
6
- metadata.gz: afcf025d29e44a480b902a15e861821b2a93c2f1cb2f266a22783e036cdffa000c24f5f48942bd6b292f051cd7ad605d87e3a1cc3a40079de4f0562444735f9f
7
- data.tar.gz: b0258ee0af5d7e4232e6a2e720789c43a8067dd0048d918f97ae031c5b85d11ac2f7af4efb36f6843ae3f2199d6d2b873447f60c8c531ab978a68268448ba0f6
6
+ metadata.gz: 3e1db6a2606eea617018f21e00294fcc4f04f9389d1ec0d66d303c2922cf2b9db0db254532667c1eae3cdd14b9658366462bc59ef5b79827b87382cc0ed71c3b
7
+ data.tar.gz: a2d8f37f0b39ec5c2771d30b1bc3260db7dbe7090d3a8818fcc5b04bee4d8d3a92e738cb57ac910e45cee148a8c42150439460a686b0e352ff5f0cfc9216f3ba
@@ -13,19 +13,35 @@ module AeActiveJobState
13
13
  # `perform_now` would go directly to around_perform
14
14
  before_enqueue do |job|
15
15
  @job_state = AeActiveJobState::JobState.create!(status: 'pending', active_job_id: job.job_id,
16
- args: job.arguments)
16
+ args: job.arguments, worker_class: job.class)
17
17
  end
18
18
 
19
19
  around_perform do |job, block|
20
- @job_state = AeActiveJobState::JobState.find_by(active_job_id: job.job_id) ||
21
- AeActiveJobState::JobState.create!(status: 'pending', active_job_id: job.job_id,
22
- args: job.arguments)
23
- job_state.run!
20
+ # This is effectively the same logic as #create_or_find_by!, the main difference is we also fail on
21
+ # RecordInvalid. This allows us to have additional uniqueness validations in the model and still fall back to
22
+ # the find_by.
23
+ #
24
+ # We do this here to prevent a race condition if the job is processed before the initial job state is created.
25
+ # This can occur in the case that the job is enqueued in a transaction and a worker picks up the work before the
26
+ # transaction commits. In this case, this create will now wait on the insertion intention lock on the
27
+ # active_job_id index created by the insert in before_enqueue, throw a record not unique, then find the correct
28
+ # state model.
29
+ #
30
+ # We continue to handle the case where the state was fully inserted before this callback is hit and the case
31
+ # where the job was never enqueued.
32
+ begin
33
+ @job_state = AeActiveJobState::JobState.create!(status: 'pending', active_job_id: job.job_id,
34
+ args: job.arguments, worker_class: job.class)
35
+ rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
36
+ @job_state = AeActiveJobState::JobState.find_by!(active_job_id: job.job_id)
37
+ end
38
+
39
+ job_state.running!
24
40
  job_state.reload
25
41
  block.call
26
- job_state.finish!
42
+ job_state.finished!
27
43
  rescue StandardError => e
28
- @job_state.fail!
44
+ @job_state.failed!
29
45
  raise e
30
46
  end
31
47
  end
@@ -14,19 +14,16 @@ module AeActiveJobState
14
14
  state :finished
15
15
  state :failed
16
16
 
17
- event :run do
18
- transitions from: :pending, to: :running
19
- after { update!(started_at: Time.now) }
17
+ event :running do
18
+ transitions to: :running, after: -> { self.started_at = Time.now }
20
19
  end
21
20
 
22
- event :fail do
23
- transitions from: :running, to: :failed
24
- after { update!(failed_at: Time.now) }
21
+ event :failed do
22
+ transitions to: :failed, after: -> { self.failed_at = Time.now }
25
23
  end
26
24
 
27
- event :finish do
28
- transitions from: :running, to: :finished
29
- after { update!(finished_at: Time.now) }
25
+ event :finished do
26
+ transitions to: :finished, after: -> { self.finished_at = Time.now }
30
27
  end
31
28
  end
32
29
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AeActiveJobState
4
- VERSION = '0.1.0'
4
+ VERSION = '1.0.1'
5
5
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddWorkerClassColumnToJobStateTable < ActiveRecord::Migration[6.0]
4
+ def change
5
+ change_table :ae_active_job_state_job_states do |t|
6
+ t.string :worker_class
7
+ end
8
+ end
9
+ end
@@ -6,8 +6,17 @@ class AeActiveJobStateGenerator < Rails::Generators::Base
6
6
  include ActiveRecord::Generators::Migration
7
7
 
8
8
  source_root File.expand_path('./ae_active_job_state/templates', __dir__)
9
+ class_option :since_version, default: '0.0.0'
10
+
11
+ MIGRATIONS = [
12
+ %w[0.1.0 create_ae_active_job_state_tables.rb],
13
+ %w[0.3.0 add_worker_class_column_to_job_state_table.rb]
14
+ ].freeze
9
15
 
10
16
  def copy_migrations
11
- migration_template 'create_ae_active_job_state_tables.rb', 'db/migrate/create_ae_active_job_state_tables.rb'
17
+ since_version = Gem::Version.new(options['since_version'])
18
+ MIGRATIONS.each do |version, file|
19
+ migration_template file, "db/migrate/#{file}" if Gem::Version.new(version) > since_version
20
+ end
12
21
  end
13
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ae_active_job_state
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - AppFolio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-18 00:00:00.000000000 Z
11
+ date: 2021-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aasm
@@ -97,6 +97,7 @@ files:
97
97
  - lib/ae_active_job_state/has_job_state.rb
98
98
  - lib/ae_active_job_state/job_state.rb
99
99
  - lib/ae_active_job_state/version.rb
100
+ - lib/generators/ae_active_job_state/templates/add_worker_class_column_to_job_state_table.rb
100
101
  - lib/generators/ae_active_job_state/templates/create_ae_active_job_state_tables.rb
101
102
  - lib/generators/ae_active_job_state_generator.rb
102
103
  homepage: https://github.com/appfolio/ae_active_job_state
@@ -118,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
119
  - !ruby/object:Gem::Version
119
120
  version: '0'
120
121
  requirements: []
121
- rubygems_version: 3.0.8
122
+ rubygems_version: 3.1.2
122
123
  signing_key:
123
124
  specification_version: 4
124
125
  summary: Store ActiveJob status in ActiveRecord