acidic_job 1.0.0.pre2 → 1.0.0.pre5

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: 6c10032604b1b559edeb2426cd79e256d904ad15444d139f4f155eee1f01dd11
4
- data.tar.gz: 4dafd1375706fd9a62cd5e0c20e576d2ab5c5ba0d10a1774182ce2dd8a62e615
3
+ metadata.gz: b8a9a11bcedbc8703e24c32db6474dfe963d8f97120c88c90dc4712026142d61
4
+ data.tar.gz: c558f6b90c1044c1320efc018fe4f9886f4af7ebab6a0c1fa8a991232e2b4065
5
5
  SHA512:
6
- metadata.gz: fd0201a2a905e1c22af8873832bdab15ec08dc233561a978e5282077edb7aeaafd41257cd7be7bc4a64249b1fc41f382f2a1c97ade23e2eb5652a4b3a5687d17
7
- data.tar.gz: 59930dbd34acf5cd52f1ec4b38173a945e2e64b0191c7d5786b863c732091bba44c2f918fd46746c138401b1e2c07228c9d68ff4c406978e431bf8745210fc14
6
+ metadata.gz: a9aef4b22eb6ee7860badda470c379d19395c60bc40072085ea3eae6ea140fd77103a07cf142a88310d90f67736300ceb3a755fe3f4283488caf36a7f872baf6
7
+ data.tar.gz: 8e1b7d428bc44f83274c3f64454d34c3467e7e701088aee862b71aec55c534a527d7d2e7e7a83fee4a94abe953284a092e8df24b55ae5c7fd195d8df968beb8f
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- acidic_job (1.0.0.pre2)
4
+ acidic_job (1.0.0.pre5)
5
5
  activerecord (>= 6.1.0)
6
6
  activesupport
7
7
 
data/README.md CHANGED
@@ -40,7 +40,7 @@ Or simply execute to install the gem yourself:
40
40
  Then, use the following command to copy over the `AcidicJob::Run` migration file.
41
41
 
42
42
  ```
43
- rails generate acidic_job
43
+ rails generate acidic_job:install
44
44
  ```
45
45
 
46
46
  ## Usage
data/UPGRADE_GUIDE.md ADDED
@@ -0,0 +1,81 @@
1
+ # AcidicJob Upgrade Guide
2
+
3
+ 1. Update version requirements in `Gemfile`
4
+
5
+ ```ruby
6
+ -gem "acidic_job"
7
+ +gem "acidic_job", "~> 1.0.0.pre1"
8
+ ```
9
+
10
+ result:
11
+ ```
12
+ Installing acidic_job 1.0.0.pre4 (was 0.7.7)
13
+ Bundle updated!
14
+ ```
15
+
16
+ 2. Generate migration for new `AcidicJob::Run` model
17
+
18
+ ```bash
19
+ rails generate acidic_job
20
+ ```
21
+
22
+ result:
23
+ ```
24
+ create db/migrate/#{yyyymmddhhmmss}_create_acidic_job_runs.rb
25
+ ```
26
+
27
+ 3. Delete any unneeded `AcidicJob::Key` records
28
+
29
+ Typically, records that are already finished do not need to be retained. Sometimes, however, applications key finished records around for some amount of time for debugging or metrics aggregation. Whatever your application's logic is for whether or not an `AcidicJob::Key` record is still needed, for all unneeded records, delete them.
30
+
31
+ For example, this would delete all finished `Key` records over 1 month old:
32
+
33
+ ```ruby
34
+ AcidicJob::Key.where(recovery_point: AcidicJob::Key::RECOVERY_POINT_FINISHED, last_run_at: ..1.month.ago).delete_all
35
+ ```
36
+
37
+ 4. Migrate `AcidicJob::Key` to `AcidicJob::Run`
38
+
39
+ `AcidicJob` ships with an upgrade module that provides a script to migrate older `Key` records to the new `Run` model.
40
+
41
+ ```ruby
42
+ AcidicJob::UpgradeService.execute
43
+ ```
44
+
45
+ This script will prepare an `insert_all` command for `Run` records by mapping the older `Key` data to the new `Run` schema. It also creates the new `Run` records with the same `id` as their `Key` counterparts, and then deletes all `Key` records successfully mapped over. Any `Key` records that were failed to be mapped over will be reported, along with the exception, in the `errored_keys` portion of the resulting hash.
46
+
47
+ result:
48
+ ```
49
+ {
50
+ run_records: <Integer>,
51
+ key_records: <Integer>,
52
+ errored_keys: <Array>
53
+ }
54
+ ```
55
+
56
+ 5. Triage remaining `AcidicJob::Key` records
57
+
58
+ If there were any `AcidicJob::Key` records that failed to be mapped to the new `Run` model, you will need to manually triage whatever the exception was. In all likelihood, the exception would be relating to the translation of the `Key#job_args` field to the `Run#serialized_job` field, as all other fields have a fairly straight-forward mapping. If you can't resolve the issue, please open an Issue in GitHub.
59
+
60
+ 6. Ensure all `AcidicJob::Staged` records are processed
61
+
62
+ `AcidicJob` still ships with an upgrade module that provides the older `Key` and `Staged` records, so this functionality will still be present to handle any existing records in your database when you deploy the updated version.
63
+
64
+ 7. Remove the old tables
65
+
66
+ Once you have successfully migrated everything over and the new system has been running smoothly for some time, you should drop the old `acidic_job_keys` and `staged_acidic_jobs` tables. We provide a migration generator just for this purpose:
67
+
68
+ ```bash
69
+ rails generate acidic_job:drop_tables
70
+ ```
71
+
72
+ result:
73
+ ```
74
+ create db/migrate/#{yyyymmddhhmmss}_drop_old_acidic_job_tables.rb
75
+ ```
76
+
77
+ You can then run the migration to have those tables removed:
78
+
79
+ ```bash
80
+ rails db:migrate
81
+ ```
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module AcidicJob
6
+ # recreate the original `Key` model
7
+ class Key < ::ActiveRecord::Base
8
+ RECOVERY_POINT_FINISHED = "FINISHED"
9
+
10
+ self.table_name = "acidic_job_keys"
11
+
12
+ serialize :error_object
13
+ serialize :job_args
14
+ serialize :workflow
15
+ store :attr_accessors
16
+ end
17
+
18
+ # recreate the original `Staged` model
19
+ class Staged < ActiveRecord::Base
20
+ self.table_name = "staged_acidic_jobs"
21
+
22
+ serialize :job_args
23
+
24
+ after_create_commit :enqueue_job
25
+
26
+ private
27
+
28
+ def enqueue_job
29
+ gid = { "staged_job_gid" => to_global_id.to_s }
30
+
31
+ if job_args.is_a?(Hash) && job_args.key?("arguments")
32
+ job_args["arguments"].concat([gid])
33
+ else
34
+ job_args.concat([gid])
35
+ end
36
+
37
+ case adapter
38
+ when "activejob"
39
+ ::ActiveJob::Base.deserialize(job_args).enqueue
40
+ when "sidekiq"
41
+ job_name.constantize.perform_async(*job_args)
42
+ else
43
+ raise UnknownJobAdapter.new(adapter: adapter)
44
+ end
45
+
46
+ # NOTE: record will be deleted after the job has successfully been performed
47
+ true
48
+ end
49
+ end
50
+
51
+ module UpgradeService
52
+ def self.execute
53
+ # prepare an array to hold the attribute hashes to be passed to `insert_all`
54
+ run_attributes = []
55
+ # prepare an array to hold any `Key` records that we couldn't successfully map to `Run` records
56
+ errored_keys = []
57
+
58
+ # iterate over all `AcidicJob::Key` records in batches,
59
+ # preparing a `Run` attribute hash to be passed to `insert_all`
60
+ ::AcidicJob::Key.find_each do |key|
61
+ # map all of the simple attributes directly
62
+ attributes = {
63
+ id: key.id,
64
+ staged: false,
65
+ idempotency_key: key.idempotency_key,
66
+ job_class: key.job_name,
67
+ last_run_at: key.last_run_at,
68
+ locked_at: key.locked_at,
69
+ recovery_point: key.recovery_point,
70
+ error_object: key.error_object,
71
+ attr_accessors: key.attr_accessors,
72
+ workflow: key.workflow,
73
+ created_at: key.created_at,
74
+ updated_at: key.updated_at
75
+ }
76
+
77
+ # prepare the more complicated `job_args` -> `serialized_job` translation
78
+ job_class = key.job_name.constantize
79
+ if defined?(::Sidekiq) && job_class.include?(::Sidekiq::Worker)
80
+ unless job_class.include?(::AcidicJob::Extensions::Sidekiq)
81
+ job_class.include(::AcidicJob::Extensions::Sidekiq)
82
+ end
83
+ job_instance = job_class.new
84
+ serialized_job = job_instance.serialize_job(*key.job_args)
85
+ elsif defined?(::ActiveJob) && job_class < ::ActiveJob::Base
86
+ unless job_class.include?(::AcidicJob::Extensions::ActiveJob)
87
+ job_class.include(::AcidicJob::Extensions::ActiveJob)
88
+ end
89
+ job_args = begin
90
+ ::ActiveJob::Arguments.deserialize(key.job_args)
91
+ rescue ::ActiveJob::DeserializationError
92
+ key.job_args
93
+ end
94
+ job_instance = job_class.new(*job_args)
95
+ serialized_job = job_instance.serialize_job
96
+ end
97
+
98
+ attributes[:serialized_job] = serialized_job
99
+ run_attributes << attributes
100
+ rescue StandardError => e
101
+ errored_keys << [e, key]
102
+ end
103
+
104
+ # insert all of the `Run` records
105
+ ::AcidicJob::Run.insert_all(run_attributes)
106
+
107
+ # delete all successfully migrated `Key` record
108
+ ::AcidicJob::Key.where(id: ::AcidicJob::Run.select(:id)).delete_all
109
+
110
+ # return a report of the upgrade migration
111
+ {
112
+ run_records: ::AcidicJob::Run.count,
113
+ key_records: ::AcidicJob::Key.count,
114
+ errored_keys: errored_keys
115
+ }
116
+ end
117
+ end
118
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- VERSION = "1.0.0.pre2"
4
+ VERSION = "1.0.0.pre5"
5
5
  end
data/lib/acidic_job.rb CHANGED
@@ -14,6 +14,7 @@ require_relative "acidic_job/extensions/sidekiq"
14
14
  require_relative "acidic_job/extensions/action_mailer"
15
15
  require_relative "acidic_job/extensions/active_job"
16
16
  require_relative "acidic_job/extensions/noticed"
17
+ require_relative "acidic_job/upgrade_service"
17
18
 
18
19
  require "active_support/concern"
19
20
 
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/active_record"
4
+
5
+ module AcidicJob
6
+ module Generators
7
+ class DropTablesGenerator < ::Rails::Generators::Base
8
+ include ActiveRecord::Generators::Migration
9
+ source_root File.expand_path("templates", __dir__)
10
+
11
+ desc "Drops the pre-1.0 tables for the AcidicJob::Key and AcidicJob::Staged models."
12
+
13
+ def copy_migration
14
+ migration_template "drop_acidic_job_keys_migration.rb.erb",
15
+ "db/migrate/drop_old_acidic_job_tables.rb",
16
+ migration_version: migration_version
17
+ end
18
+
19
+ protected
20
+
21
+ def migration_version
22
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/active_record"
4
+
5
+ module AcidicJob
6
+ module Generators
7
+ class InstallGenerator < ::Rails::Generators::Base
8
+ include ActiveRecord::Generators::Migration
9
+ source_root File.expand_path("templates", __dir__)
10
+
11
+ desc "Generates a migration for the AcidicJob::Run table."
12
+
13
+ # Copies the migration template to db/migrate.
14
+ def copy_acidic_job_runs_migration_files
15
+ migration_template "create_acidic_job_runs_migration.rb.erb",
16
+ "db/migrate/create_acidic_job_runs.rb",
17
+ migration_version: migration_version
18
+ end
19
+
20
+ protected
21
+
22
+ def migration_version
23
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,4 +1,4 @@
1
- class CreateAcidicJobRuns < <%= migration_class %>
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
  create_table :acidic_job_runs do |t|
4
4
  t.boolean :staged, null: false, default: -> { false }
@@ -0,0 +1,27 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ drop_table :acidic_job_keys do |t|
4
+ t.string :idempotency_key, null: false
5
+ t.string :job_name, null: false
6
+ t.text :job_args, null: true
7
+ t.datetime :last_run_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
8
+ t.datetime :locked_at, null: true
9
+ t.string :recovery_point, null: false
10
+ t.text :error_object
11
+ t.text :attr_accessors
12
+ t.text :workflow
13
+ t.timestamps
14
+
15
+ t.index %i[idempotency_key job_name job_args],
16
+ unique: true,
17
+ name: "idx_acidic_job_keys_on_idempotency_key_n_job_name_n_job_args"
18
+ end
19
+
20
+ drop_table :staged_acidic_jobs do |t|
21
+ t.string :adapter, null: false
22
+ t.string :job_name, null: false
23
+ t.text :job_args, null: true
24
+ t.timestamps
25
+ end
26
+ end
27
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acidic_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre2
4
+ version: 1.0.0.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - fractaledmind
@@ -68,6 +68,7 @@ files:
68
68
  - LICENSE
69
69
  - README.md
70
70
  - Rakefile
71
+ - UPGRADE_GUIDE.md
71
72
  - acidic_job.gemspec
72
73
  - bin/console
73
74
  - bin/setup
@@ -86,9 +87,12 @@ files:
86
87
  - lib/acidic_job/run.rb
87
88
  - lib/acidic_job/staging.rb
88
89
  - lib/acidic_job/step.rb
90
+ - lib/acidic_job/upgrade_service.rb
89
91
  - lib/acidic_job/version.rb
90
- - lib/generators/acidic_job_generator.rb
91
- - lib/generators/templates/create_acidic_job_runs_migration.rb.erb
92
+ - lib/generators/acidic_job/drop_tables_generator.rb
93
+ - lib/generators/acidic_job/install_generator.rb
94
+ - lib/generators/acidic_job/templates/create_acidic_job_runs_migration.rb.erb
95
+ - lib/generators/acidic_job/templates/drop_acidic_job_keys_migration.rb.erb
92
96
  homepage: https://github.com/fractaledmind/acidic_job
93
97
  licenses:
94
98
  - MIT
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rails/generators"
4
- require "rails/generators/active_record"
5
-
6
- class AcidicJobGenerator < ActiveRecord::Generators::Base
7
- # ActiveRecord::Generators::Base inherits from Rails::Generators::NamedBase
8
- # which requires a NAME parameter for the new table name.
9
- # Our generator always uses "acidic_job_runs", so we just set a random name here.
10
- argument :name, type: :string, default: "random_name"
11
-
12
- source_root File.expand_path("templates", __dir__)
13
-
14
- def self.next_migration_number(_path)
15
- if instance_variable_defined?("@prev_migration_nr") # :nocov:
16
- @prev_migration_nr += 1
17
- else
18
- @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
19
- end
20
-
21
- @prev_migration_nr.to_s
22
- end
23
-
24
- # Copies the migration template to db/migrate.
25
- def copy_acidic_job_runs_migration_files
26
- migration_template "create_acidic_job_runs_migration.rb.erb",
27
- "db/migrate/create_acidic_job_runs.rb"
28
- end
29
-
30
- protected
31
-
32
- def migration_class
33
- ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
34
- end
35
- end