good_pipeline 0.2.0 → 0.2.2

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: ecdb6ba1864f5d087489e9f6b6fb74436af9da054fe2bf2d9443a34327d75ac8
4
- data.tar.gz: 67d2ed61cd52229e854872e04e8e5da18ec3d95981a8287cf7c28742ebbb5f69
3
+ metadata.gz: e52af813bd86f0de3d905a3f591209e0a155e0b5c28e3a76f963f1c2cdbd8232
4
+ data.tar.gz: 3a48213db593949e7f9afff0f341cf29dfdb90d4972b20b4c5e48091cb86bab1
5
5
  SHA512:
6
- metadata.gz: ea301d87d187f22b3f35585b3a08fc9ff1d94d3ae793bedfe2efcbdc1224b828af50beff05a36cebc81b1b0b8167b62d40d016178c6a5488210b8809893c25cc
7
- data.tar.gz: 4afe3fdb1d05f01773a3e4bca22711e1751a83db47a0db49dc955feff2402b81c57a0d60f6e5a1b65d21e06a40f571f07158dcb744fc3029996285ff23cf4e16
6
+ metadata.gz: 7bc3d7e1181b852bbc795f1e65ef9b2764645ffc13d7d860f444074158c741202ddae188253c50cb12a44da9958fe6403b2435fef6ec71d9172a35b46816da55
7
+ data.tar.gz: 22b59ba7dba841a6d55559c27a7427032bad94ed1fd3e336f2d53997ee4a24bf2f8c193d77e743095e4c5c73b948975b0f85228d63839eba367af1dc441f8456
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.2] - 2026-03-24
4
+
5
+ ### Fixed
6
+
7
+ - **Fan-in step race condition** — replaced `FOR UPDATE SKIP LOCKED` with `FOR UPDATE` in `Coordinator.try_enqueue_step`. When multiple upstreams of a fan-in step completed simultaneously, `SKIP LOCKED` caused concurrent callers to silently give up, leaving the downstream step stranded in `pending` forever. Blocking locks ensure the last caller always sees all upstreams satisfied and enqueues the step. Existing `pending?` and `good_job_id` guards provide idempotency.
8
+
9
+ ## [0.2.1] - 2026-03-24
10
+
11
+ ### Fixed
12
+
13
+ - **`dependent: :destroy` on pipeline steps** — switched from `delete_all` to `destroy` so that destroying a pipeline properly triggers StepRecord's cascading cleanup of dependency records.
14
+ - **Redundant database indexes** — removed single-column indexes on `steps(pipeline_id)` and `chains(upstream_pipeline_id)` that were already covered by their respective composite indexes.
15
+
3
16
  ## [0.2.0] - 2026-03-24
4
17
 
5
18
  ### Added
@@ -27,7 +27,7 @@ module GoodPipeline
27
27
  class_name: "GoodPipeline::StepRecord",
28
28
  foreign_key: :pipeline_id,
29
29
  inverse_of: :pipeline,
30
- dependent: :delete_all
30
+ dependent: :destroy
31
31
 
32
32
  has_many :dependencies,
33
33
  class_name: "GoodPipeline::DependencyRecord",
@@ -18,7 +18,7 @@ class CreateGoodPipelineTables < ActiveRecord::Migration[<%= ActiveRecord::Migra
18
18
  add_index :good_pipeline_pipelines, :status
19
19
 
20
20
  create_table :good_pipeline_steps, id: :uuid do |t|
21
- t.references :pipeline, null: false, foreign_key: { to_table: :good_pipeline_pipelines }, type: :uuid
21
+ t.references :pipeline, null: false, foreign_key: { to_table: :good_pipeline_pipelines }, type: :uuid, index: false
22
22
  t.string :key, null: false
23
23
  t.string :job_class, null: false
24
24
  t.jsonb :params, null: false, default: {}
@@ -45,7 +45,7 @@ class CreateGoodPipelineTables < ActiveRecord::Migration[<%= ActiveRecord::Migra
45
45
  end
46
46
 
47
47
  create_table :good_pipeline_chains, id: :uuid do |t|
48
- t.references :upstream_pipeline, null: false, foreign_key: { to_table: :good_pipeline_pipelines }, type: :uuid
48
+ t.references :upstream_pipeline, null: false, foreign_key: { to_table: :good_pipeline_pipelines }, type: :uuid, index: false
49
49
  t.references :downstream_pipeline, null: false, foreign_key: { to_table: :good_pipeline_pipelines }, type: :uuid
50
50
  end
51
51
 
@@ -17,7 +17,7 @@ module GoodPipeline
17
17
  recompute_pipeline = nil
18
18
 
19
19
  StepRecord.transaction do
20
- locked_step = StepRecord.lock("FOR UPDATE SKIP LOCKED").find_by(id: step_id)
20
+ locked_step = StepRecord.lock("FOR UPDATE").find_by(id: step_id)
21
21
  return unless locked_step&.pending?
22
22
  return if locked_step.good_job_id.present?
23
23
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GoodPipeline
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: good_pipeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ali Hamdi Ali Fadel