ae_active_job_state 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 06a4c9233311e99e2aa3f14bcf7310c36ab0221ed9fe8cd01d0c9b660c9cd6f1
4
+ data.tar.gz: 4d15d5d24db0a18f773a05695e6139d3acfdbabdbdee91080b218e0eb31d00e1
5
+ SHA512:
6
+ metadata.gz: afcf025d29e44a480b902a15e861821b2a93c2f1cb2f266a22783e036cdffa000c24f5f48942bd6b292f051cd7ad605d87e3a1cc3a40079de4f0562444735f9f
7
+ data.tar.gz: b0258ee0af5d7e4232e6a2e720789c43a8067dd0048d918f97ae031c5b85d11ac2f7af4efb36f6843ae3f2199d6d2b873447f60c8c531ab978a68268448ba0f6
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2020-2020 AppFolio inc
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/ae_active_job_state/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'ae_active_job_state'
7
+ spec.version = AeActiveJobState::VERSION
8
+ spec.platform = Gem::Platform::RUBY
9
+ spec.author = 'AppFolio'
10
+ spec.email = 'opensource@appfolio.com'
11
+ spec.description = 'Store ActiveJob status in ActiveRecord'
12
+ spec.summary = spec.description
13
+ spec.homepage = 'https://github.com/appfolio/ae_active_job_state'
14
+ spec.license = 'MIT'
15
+ spec.files = Dir['**/*'].select { |f| f[%r{^(lib/|LICENSE.txt|.*gemspec)}] }
16
+ spec.require_paths = ['lib']
17
+
18
+ spec.add_dependency 'aasm', '~> 5.1'
19
+ spec.add_dependency 'activejob', '>= 6', '< 7'
20
+ spec.add_dependency 'activerecord', '>= 6', '< 7'
21
+ spec.add_dependency 'activesupport', '>= 6', '< 7'
22
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ae_active_job_state/version'
4
+ require 'active_support'
5
+ require 'active_job'
6
+ require 'active_record'
7
+ require 'aasm'
8
+
9
+ module AeActiveJobState
10
+ end
11
+
12
+ require 'ae_active_job_state/job_state'
13
+ require 'ae_active_job_state/has_job_state'
14
+ require 'ae_active_job_state/delete_old_job_states_job'
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AeActiveJobState
4
+ class DeleteOldJobStatesJob < ActiveJob::Base
5
+ def perform(older_than_days: 30)
6
+ JobState.where('updated_at < ?', older_than_days.days.ago).destroy_all
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AeActiveJobState
4
+ module HasJobState
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attr_accessor :job_state
9
+
10
+ delegate :id, :progress, :result, to: :job_state
11
+
12
+ # before_enqueue is only triggered on `perform_later`
13
+ # `perform_now` would go directly to around_perform
14
+ before_enqueue do |job|
15
+ @job_state = AeActiveJobState::JobState.create!(status: 'pending', active_job_id: job.job_id,
16
+ args: job.arguments)
17
+ end
18
+
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!
24
+ job_state.reload
25
+ block.call
26
+ job_state.finish!
27
+ rescue StandardError => e
28
+ @job_state.fail!
29
+ raise e
30
+ end
31
+ end
32
+
33
+ def set_job_progress!(progress)
34
+ job_state.update!(progress: progress)
35
+ end
36
+
37
+ def set_job_result!(result)
38
+ job_state.update!(result: result)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AeActiveJobState
4
+ class JobState < ActiveRecord::Base
5
+ self.table_name = 'ae_active_job_state_job_states'
6
+
7
+ validates :status, presence: true
8
+ validates :active_job_id, presence: true, uniqueness: { case_sensitive: false }
9
+
10
+ include AASM
11
+ aasm(column: 'status') do
12
+ state :pending, initial: true
13
+ state :running
14
+ state :finished
15
+ state :failed
16
+
17
+ event :run do
18
+ transitions from: :pending, to: :running
19
+ after { update!(started_at: Time.now) }
20
+ end
21
+
22
+ event :fail do
23
+ transitions from: :running, to: :failed
24
+ after { update!(failed_at: Time.now) }
25
+ end
26
+
27
+ event :finish do
28
+ transitions from: :running, to: :finished
29
+ after { update!(finished_at: Time.now) }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AeActiveJobState
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateAeActiveJobStateTables < ActiveRecord::Migration[6.0]
4
+ def change
5
+ create_table :ae_active_job_state_job_states do |t|
6
+ t.timestamps null: false
7
+
8
+ t.string :status, null: false
9
+ t.json :args
10
+ t.json :result
11
+ t.json :progress
12
+
13
+ t.datetime :started_at
14
+ t.datetime :finished_at
15
+ t.datetime :failed_at
16
+
17
+ t.string :active_job_id, null: false, index: { unique: true }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/active_record/migration'
4
+
5
+ class AeActiveJobStateGenerator < Rails::Generators::Base
6
+ include ActiveRecord::Generators::Migration
7
+
8
+ source_root File.expand_path('./ae_active_job_state/templates', __dir__)
9
+
10
+ def copy_migrations
11
+ migration_template 'create_ae_active_job_state_tables.rb', 'db/migrate/create_ae_active_job_state_tables.rb'
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ae_active_job_state
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - AppFolio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aasm
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activejob
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '7'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '6'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '7'
47
+ - !ruby/object:Gem::Dependency
48
+ name: activerecord
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '6'
54
+ - - "<"
55
+ - !ruby/object:Gem::Version
56
+ version: '7'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '6'
64
+ - - "<"
65
+ - !ruby/object:Gem::Version
66
+ version: '7'
67
+ - !ruby/object:Gem::Dependency
68
+ name: activesupport
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '6'
74
+ - - "<"
75
+ - !ruby/object:Gem::Version
76
+ version: '7'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '6'
84
+ - - "<"
85
+ - !ruby/object:Gem::Version
86
+ version: '7'
87
+ description: Store ActiveJob status in ActiveRecord
88
+ email: opensource@appfolio.com
89
+ executables: []
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - LICENSE.txt
94
+ - ae_active_job_state.gemspec
95
+ - lib/ae_active_job_state.rb
96
+ - lib/ae_active_job_state/delete_old_job_states_job.rb
97
+ - lib/ae_active_job_state/has_job_state.rb
98
+ - lib/ae_active_job_state/job_state.rb
99
+ - lib/ae_active_job_state/version.rb
100
+ - lib/generators/ae_active_job_state/templates/create_ae_active_job_state_tables.rb
101
+ - lib/generators/ae_active_job_state_generator.rb
102
+ homepage: https://github.com/appfolio/ae_active_job_state
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubygems_version: 3.0.8
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Store ActiveJob status in ActiveRecord
125
+ test_files: []