acidic_job 1.0.0.rc4 → 1.0.0.rc6

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/acidic_job/application.css +15 -0
  3. data/app/controllers/acidic_job/application_controller.rb +4 -0
  4. data/app/jobs/acidic_job/application_job.rb +4 -0
  5. data/app/mailers/acidic_job/application_mailer.rb +6 -0
  6. data/app/models/acidic_job/{record.rb → application_record.rb} +2 -2
  7. data/app/models/acidic_job/entry.rb +4 -4
  8. data/app/models/acidic_job/execution.rb +4 -4
  9. data/app/models/acidic_job/value.rb +1 -1
  10. data/app/views/layouts/acidic_job/application.html.erb +17 -0
  11. data/lib/acidic_job/builder.rb +2 -2
  12. data/lib/acidic_job/context.rb +4 -4
  13. data/lib/acidic_job/log_subscriber.rb +1 -1
  14. data/lib/acidic_job/serializers/range_serializer.rb +1 -1
  15. data/lib/acidic_job/testing.rb +3 -3
  16. data/lib/acidic_job/version.rb +1 -1
  17. data/lib/acidic_job/workflow.rb +4 -4
  18. data/lib/acidic_job.rb +1 -1
  19. metadata +23 -52
  20. data/.codacy.yml +0 -4
  21. data/.github/FUNDING.yml +0 -13
  22. data/.github/workflows/main.yml +0 -38
  23. data/.gitignore +0 -18
  24. data/.rubocop-https---www-goodcop-style-base-yml +0 -1051
  25. data/.rubocop.yml +0 -11
  26. data/.ruby-version +0 -1
  27. data/Gemfile +0 -5
  28. data/Gemfile.lock +0 -209
  29. data/Rakefile +0 -16
  30. data/TODO +0 -77
  31. data/UPGRADE_GUIDE.md +0 -81
  32. data/acidic_job.gemspec +0 -50
  33. data/bin/console +0 -21
  34. data/bin/setup +0 -8
  35. data/bin/test_all +0 -26
  36. data/blog_post.md +0 -28
  37. data/combustion/log/test.log +0 -0
  38. data/gemfiles/rails_7.0.gemfile +0 -11
  39. data/gemfiles/rails_7.1.gemfile +0 -11
  40. data/gemfiles/rails_7.2.gemfile +0 -11
  41. data/gemfiles/rails_8.0.gemfile +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0bb00fc13b3abf7f095376244b399d7423b63d3b57c4f545e328c9d136e8c058
4
- data.tar.gz: 0cf2975089e10e7df69972f89b60ffaaa9e5f81e82bc6556e974557ca615e18d
3
+ metadata.gz: '004839711b3d3c8bec8ab08dec1d4c5c855fa4f69f659b9c220c151d5003d6d4'
4
+ data.tar.gz: 46dd79d7e3a83c019dd449c3846986c358b8f572ba3b2ca811087cd567e105e2
5
5
  SHA512:
6
- metadata.gz: f9beab588dc08ffaba793c9d019f3a1e92bce8964487fbfeba97e2be2d5bf9bf17022c49f0269e85a36b42953e62798feb3667ac1ce0423d31b80b9ac024b1a4
7
- data.tar.gz: 9fe26ec816581a4b3544da0723df644a7515f4e6f75a75d85cb0be37a77461854edf34bab0dddd490bc4f992e0835f9181329a92709bc7de94900895706ddcab
6
+ metadata.gz: ba94864fc9c8b710959bd21ec0f53d4a42bacce974e5d985d92060ffe3215102889573dc5b04bbe697a03506df7c270d20fbfc73d5316e04b977c2d47f0588b8
7
+ data.tar.gz: caee8a65b86e58266730487f52185b9c5dcb64801f6db241b8ffa256d8d741ea9668a673371bdca1da806cc8dff8c62f742a69f86086442dac4b64d63649ec52
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module AcidicJob
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AcidicJob
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module AcidicJob
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- class Record < ActiveRecord::Base
4
+ class ApplicationRecord < ActiveRecord::Base
5
5
  self.abstract_class = true
6
6
 
7
7
  connects_to(**AcidicJob.connects_to) if AcidicJob.connects_to
8
8
  end
9
9
  end
10
10
 
11
- ActiveSupport.run_load_hooks :acidic_job_record, AcidicJob::Record
11
+ ActiveSupport.run_load_hooks :acidic_job_record, AcidicJob::ApplicationRecord
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- class Entry < Record
4
+ class Entry < ApplicationRecord
5
5
  belongs_to :execution, class_name: "AcidicJob::Execution"
6
6
 
7
7
  serialize :data, coder: AcidicJob::Serializer
8
8
 
9
- scope :for_step, -> (step) { where(step: step) }
10
- scope :for_action, -> (action) { where(action: action) }
11
- scope :ordered, -> { order(timestamp: :asc) }
9
+ scope :for_step, ->(step) { where(step: step) }
10
+ scope :for_action, ->(action) { where(action: action) }
11
+ scope :ordered, -> { order(timestamp: :asc, created_at: :asc) }
12
12
 
13
13
  def self.most_recent
14
14
  order(created_at: :desc).first
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- class Execution < Record
4
+ class Execution < ApplicationRecord
5
5
  has_many :entries, class_name: "AcidicJob::Entry", dependent: :destroy
6
6
  has_many :values, class_name: "AcidicJob::Value", dependent: :destroy
7
7
 
@@ -14,9 +14,9 @@ module AcidicJob
14
14
  where(recover_to: FINISHED_RECOVERY_POINT)
15
15
  }
16
16
  scope :outstanding, -> {
17
- where.not(recover_to: FINISHED_RECOVERY_POINT).or(where(recover_to: [nil, ""]))
17
+ where.not(recover_to: FINISHED_RECOVERY_POINT).or(where(recover_to: [ nil, "" ]))
18
18
  }
19
- scope :clearable, -> (finished_before: AcidicJob.clear_finished_executions_after.ago) {
19
+ scope :clearable, ->(finished_before: AcidicJob.clear_finished_executions_after.ago) {
20
20
  finished.where(last_run_at: ...finished_before)
21
21
  }
22
22
 
@@ -34,7 +34,7 @@ module AcidicJob
34
34
  step: step,
35
35
  action: action,
36
36
  timestamp: timestamp,
37
- data: kwargs.except(:ignored),
37
+ data: kwargs.except(:ignored)
38
38
  })
39
39
  end
40
40
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- class Value < Record
4
+ class Value < ApplicationRecord
5
5
  belongs_to :execution, class_name: "AcidicJob::Execution"
6
6
 
7
7
  serialize :value, coder: AcidicJob::Serializer
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Acidic job</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= yield :head %>
9
+
10
+ <%= stylesheet_link_tag "acidic_job/application", media: "all" %>
11
+ </head>
12
+ <body>
13
+
14
+ <%= yield %>
15
+
16
+ </body>
17
+ </html>
@@ -28,9 +28,9 @@ module AcidicJob
28
28
 
29
29
  definition = {
30
30
  "meta" => {
31
- "version" => VERSION,
31
+ "version" => VERSION
32
32
  },
33
- "steps" => {},
33
+ "steps" => {}
34
34
  }
35
35
 
36
36
  definition.tap do |workflow|
@@ -12,21 +12,21 @@ module AcidicJob
12
12
  {
13
13
  execution_id: @execution.id,
14
14
  key: key,
15
- value: value,
15
+ value: value
16
16
  }
17
17
  end
18
18
 
19
19
  case AcidicJob::Value.connection.adapter_name.downcase.to_sym
20
20
  when :postgresql, :sqlite
21
- AcidicJob::Value.upsert_all(records, unique_by: [:execution_id, :key])
21
+ AcidicJob::Value.upsert_all(records, unique_by: [ :execution_id, :key ])
22
22
  when :mysql2, :mysql, :trilogy
23
23
  AcidicJob::Value.upsert_all(records)
24
24
  else
25
25
  # Fallback for other adapters - try with unique_by first, fall back without
26
26
  begin
27
- AcidicJob::Value.upsert_all(records, unique_by: [:execution_id, :key])
27
+ AcidicJob::Value.upsert_all(records, unique_by: [ :execution_id, :key ])
28
28
  rescue ArgumentError => e
29
- if e.message.include?('does not support :unique_by')
29
+ if e.message.include?("does not support :unique_by")
30
30
  AcidicJob::Value.upsert_all(records)
31
31
  else
32
32
  raise
@@ -37,7 +37,7 @@ module AcidicJob
37
37
  end
38
38
 
39
39
  private def formatted_error(error)
40
- [error.class, error.message].compact.join(" ")
40
+ [ error.class, error.message ].compact.join(" ")
41
41
  end
42
42
 
43
43
  # Use the logger configured for AcidicJob
@@ -9,7 +9,7 @@ module AcidicJob
9
9
  KEYS = %w[begin end exclude_end].freeze
10
10
 
11
11
  def serialize(range)
12
- args = Arguments.serialize([range.begin, range.end, range.exclude_end?])
12
+ args = Arguments.serialize([ range.begin, range.end, range.exclude_end? ])
13
13
  super(KEYS.zip(args).to_h)
14
14
  end
15
15
 
@@ -26,7 +26,7 @@ module AcidicJob
26
26
  # except that any `transaction` strategies for any ORMs are replaced with a `deletion` strategy.
27
27
  private def transaction_free_cleaners_for(original_cleaners)
28
28
  non_transaction_cleaners = original_cleaners.dup.to_h do |(orm, opts), cleaner|
29
- [[orm, opts], ensure_no_transaction_strategies_for(cleaner)]
29
+ [ [ orm, opts ], ensure_no_transaction_strategies_for(cleaner) ]
30
30
  end
31
31
  ::DatabaseCleaner::Cleaners.new(non_transaction_cleaners)
32
32
  end
@@ -55,12 +55,12 @@ module AcidicJob
55
55
  .name # "DatabaseCleaner::ActiveRecord::Truncation"
56
56
  .rpartition("::") # ["DatabaseCleaner::ActiveRecord", "::", "Truncation"]
57
57
  .first # "DatabaseCleaner::ActiveRecord"
58
- deletion_strategy_class_name = [strategy_namespace, "::", "Deletion"].join
58
+ deletion_strategy_class_name = [ strategy_namespace, "::", "Deletion" ].join
59
59
  deletion_strategy_class = deletion_strategy_class_name.constantize
60
60
  instance_variable_hash = strategy.instance_variables.to_h do |var|
61
61
  [
62
62
  var.to_s.remove("@"),
63
- strategy.instance_variable_get(var),
63
+ strategy.instance_variable_get(var)
64
64
  ]
65
65
  end
66
66
  options = instance_variable_hash.except("db", "connection_class")
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- VERSION = "1.0.0.rc4"
4
+ VERSION = "1.0.0.rc6"
5
5
  end
@@ -31,12 +31,12 @@ module AcidicJob
31
31
  AcidicJob.instrument(:initialize_workflow, definition: workflow_definition) do
32
32
  transaction_args = case ::ActiveRecord::Base.connection.adapter_name.downcase.to_sym
33
33
  # SQLite doesn't support `serializable` transactions
34
- when :sqlite
34
+ when :sqlite
35
35
  {}
36
- else
36
+ else
37
37
  { isolation: :serializable }
38
38
  end
39
- idempotency_key = Digest::SHA256.hexdigest(JSON.generate([self.class.name, unique_by], strict: true))
39
+ idempotency_key = Digest::SHA256.hexdigest(JSON.generate([ self.class.name, unique_by ], strict: true))
40
40
 
41
41
  @__acidic_job_execution__ = ::ActiveRecord::Base.transaction(**transaction_args) do
42
42
  record = Execution.find_by(idempotency_key: idempotency_key)
@@ -162,7 +162,7 @@ module AcidicJob
162
162
  step: curr_step,
163
163
  action: :succeeded,
164
164
  ignored: {
165
- result: result,
165
+ result: result
166
166
  }
167
167
  )
168
168
  next_step
data/lib/acidic_job.rb CHANGED
@@ -22,7 +22,7 @@ module AcidicJob
22
22
 
23
23
  mattr_accessor :logger, default: DEFAULT_LOGGER
24
24
  mattr_accessor :connects_to
25
- mattr_accessor :plugins, default: [Plugins::TransactionalStep]
25
+ mattr_accessor :plugins, default: [ Plugins::TransactionalStep ]
26
26
  mattr_accessor :clear_finished_executions_after, default: 1.week
27
27
 
28
28
  def instrument(channel, **options, &block)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acidic_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc4
4
+ version: 1.0.0.rc6
5
5
  platform: ruby
6
6
  authors:
7
- - fractaledmind
8
- bindir: exe
7
+ - Stephen Margheim
8
+ bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-13 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: json
@@ -79,36 +79,22 @@ dependencies:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
81
  version: '7.1'
82
- - !ruby/object:Gem::Dependency
83
- name: actionmailer
84
- requirement: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- version: '7.1'
89
- type: :development
90
- prerelease: false
91
- version_requirements: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- version: '7.1'
96
82
  - !ruby/object:Gem::Dependency
97
83
  name: chaotic_job
98
84
  requirement: !ruby/object:Gem::Requirement
99
85
  requirements:
100
86
  - - ">="
101
87
  - !ruby/object:Gem::Version
102
- version: '0'
88
+ version: 0.11.2
103
89
  type: :development
104
90
  prerelease: false
105
91
  version_requirements: !ruby/object:Gem::Requirement
106
92
  requirements:
107
93
  - - ">="
108
94
  - !ruby/object:Gem::Version
109
- version: '0'
95
+ version: 0.11.2
110
96
  - !ruby/object:Gem::Dependency
111
- name: combustion
97
+ name: simplecov
112
98
  requirement: !ruby/object:Gem::Requirement
113
99
  requirements:
114
100
  - - ">="
@@ -136,7 +122,7 @@ dependencies:
136
122
  - !ruby/object:Gem::Version
137
123
  version: '0'
138
124
  - !ruby/object:Gem::Dependency
139
- name: rake
125
+ name: mysql2
140
126
  requirement: !ruby/object:Gem::Requirement
141
127
  requirements:
142
128
  - - ">="
@@ -150,7 +136,7 @@ dependencies:
150
136
  - !ruby/object:Gem::Version
151
137
  version: '0'
152
138
  - !ruby/object:Gem::Dependency
153
- name: rubocop
139
+ name: pg
154
140
  requirement: !ruby/object:Gem::Requirement
155
141
  requirements:
156
142
  - - ">="
@@ -164,7 +150,7 @@ dependencies:
164
150
  - !ruby/object:Gem::Version
165
151
  version: '0'
166
152
  - !ruby/object:Gem::Dependency
167
- name: simplecov
153
+ name: sqlite3
168
154
  requirement: !ruby/object:Gem::Requirement
169
155
  requirements:
170
156
  - - ">="
@@ -178,7 +164,7 @@ dependencies:
178
164
  - !ruby/object:Gem::Version
179
165
  version: '0'
180
166
  - !ruby/object:Gem::Dependency
181
- name: sqlite3
167
+ name: actionmailer
182
168
  requirement: !ruby/object:Gem::Requirement
183
169
  requirements:
184
170
  - - ">="
@@ -191,41 +177,26 @@ dependencies:
191
177
  - - ">="
192
178
  - !ruby/object:Gem::Version
193
179
  version: '0'
194
- description: Idempotent operations for Rails apps, built on top of ActiveJob.
180
+ description: "Write reliable and repeatable multi-step distributed operations that
181
+ are Atomic ⚛️, Consistent \U0001F916, Isolated \U0001F574\U0001F3FC, and Durable
182
+ ⛰️."
195
183
  email:
196
184
  - stephen.margheim@gmail.com
197
185
  executables: []
198
186
  extensions: []
199
187
  extra_rdoc_files: []
200
188
  files:
201
- - ".codacy.yml"
202
- - ".github/FUNDING.yml"
203
- - ".github/workflows/main.yml"
204
- - ".gitignore"
205
- - ".rubocop-https---www-goodcop-style-base-yml"
206
- - ".rubocop.yml"
207
- - ".ruby-version"
208
- - Gemfile
209
- - Gemfile.lock
210
189
  - LICENSE
211
190
  - README.md
212
- - Rakefile
213
- - TODO
214
- - UPGRADE_GUIDE.md
215
- - acidic_job.gemspec
191
+ - app/assets/stylesheets/acidic_job/application.css
192
+ - app/controllers/acidic_job/application_controller.rb
193
+ - app/jobs/acidic_job/application_job.rb
194
+ - app/mailers/acidic_job/application_mailer.rb
195
+ - app/models/acidic_job/application_record.rb
216
196
  - app/models/acidic_job/entry.rb
217
197
  - app/models/acidic_job/execution.rb
218
- - app/models/acidic_job/record.rb
219
198
  - app/models/acidic_job/value.rb
220
- - bin/console
221
- - bin/setup
222
- - bin/test_all
223
- - blog_post.md
224
- - combustion/log/test.log
225
- - gemfiles/rails_7.0.gemfile
226
- - gemfiles/rails_7.1.gemfile
227
- - gemfiles/rails_7.2.gemfile
228
- - gemfiles/rails_8.0.gemfile
199
+ - app/views/layouts/acidic_job/application.html.erb
229
200
  - lib/acidic_job.rb
230
201
  - lib/acidic_job/arguments.rb
231
202
  - lib/acidic_job/builder.rb
@@ -260,14 +231,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
260
231
  requirements:
261
232
  - - ">="
262
233
  - !ruby/object:Gem::Version
263
- version: 2.7.0
234
+ version: 3.0.0
264
235
  required_rubygems_version: !ruby/object:Gem::Requirement
265
236
  requirements:
266
237
  - - ">="
267
238
  - !ruby/object:Gem::Version
268
239
  version: '0'
269
240
  requirements: []
270
- rubygems_version: 3.6.3
241
+ rubygems_version: 3.6.7
271
242
  specification_version: 4
272
- summary: Idempotent operations for Rails apps, built on top of ActiveJob.
243
+ summary: "\U0001F9EA Durable execution workflows for Active Job"
273
244
  test_files: []
data/.codacy.yml DELETED
@@ -1,4 +0,0 @@
1
- ---
2
- exclude_paths:
3
- - "**/*.md"
4
- - "LICENSE"
data/.github/FUNDING.yml DELETED
@@ -1,13 +0,0 @@
1
- # These are supported funding model platforms
2
-
3
- github: fractaledmind
4
- patreon: # Replace with a single Patreon username
5
- open_collective: # Replace with a single Open Collective username
6
- ko_fi: # Replace with a single Ko-fi username
7
- tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
- community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
- liberapay: # Replace with a single Liberapay username
10
- issuehunt: # Replace with a single IssueHunt username
11
- otechie: # Replace with a single Otechie username
12
- lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13
- custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
@@ -1,38 +0,0 @@
1
- name: CI
2
-
3
- on: [push]
4
-
5
- jobs:
6
- build:
7
- runs-on: ubuntu-latest
8
-
9
- strategy:
10
- fail-fast: false
11
- matrix:
12
- ruby: ["3.0", "3.1", "3.2", "3.3"]
13
- rails: [ "7.1", "7.2", "8.0"]
14
- exclude:
15
- - ruby: "3.0"
16
- rails: "8.0"
17
- - ruby: "3.1"
18
- rails: "8.0"
19
- - ruby: "3.0"
20
- rails: "7.2"
21
-
22
- env:
23
- BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_${{ matrix.rails }}.gemfile
24
-
25
- steps:
26
- - uses: actions/checkout@v4
27
-
28
- - name: Set up Ruby
29
- # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
30
- # change this to (see https://github.com/ruby/setup-ruby#versioning):
31
- uses: ruby/setup-ruby@v1
32
- with:
33
- bundler-cache: true # 'bundle install' and cache gems
34
- ruby-version: ${{ matrix.ruby }}
35
-
36
- - name: Run the default task
37
- run: bundle exec rake
38
- timeout-minutes: 2
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- .DS_Store
10
- /test/database.sqlite
11
- slides.md
12
- /test/dummy
13
- /test/log
14
- /database.sqlite
15
- /test/combustion/database.sqlite*
16
- /test/combustion/log/test.log
17
- /test/combustion/tmp/*
18
- /gemfiles/*.lock