Skip to content

Commit de0d3b7

Browse files
committed
fix(publish pacts): handle race condition when creating pact version
1 parent 052055d commit de0d3b7

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

lib/pact_broker/pacts/pact_version.rb

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
require 'sequel'
2+
require 'pact_broker/repositories/helpers'
23

34
module PactBroker
45
module Pacts
56
class PactVersion < Sequel::Model(:pact_versions)
7+
plugin :timestamps
68
one_to_many :pact_publications, reciprocal: :pact_version
79
one_to_many :verifications, reciprocal: :verification, order: :id, :class => "PactBroker::Domain::Verification"
810
associate(:many_to_one, :provider, class: "PactBroker::Domain::Pacticipant", key: :provider_id, primary_key: :id)
911
associate(:many_to_one, :consumer, class: "PactBroker::Domain::Pacticipant", key: :consumer_id, primary_key: :id)
1012

13+
dataset_module do
14+
include PactBroker::Repositories::Helpers
15+
end
16+
1117
def name
1218
"Pact between #{consumer_name} and #{provider_name}"
1319
end
@@ -45,9 +51,11 @@ def consumer_versions
4551
def latest_consumer_version_number
4652
latest_consumer_version.number
4753
end
48-
end
4954

50-
PactVersion.plugin :timestamps
55+
def upsert
56+
self.class.upsert(to_hash, [:consumer_id, :provider_id, :sha])
57+
end
58+
end
5159
end
5260
end
5361

lib/pact_broker/pacts/repository.rb

+4-6
Original file line numberDiff line numberDiff line change
@@ -292,15 +292,13 @@ def find_or_create_pact_version consumer_id, provider_id, pact_version_sha, json
292292
end
293293

294294
def create_pact_version consumer_id, provider_id, sha, json_content
295-
logger.debug("Creating new pact version for sha #{sha}")
296-
# Content.from_json(json_content).with_ids.to_json
297-
pact_version = PactVersion.new(
295+
PactVersion.new(
298296
consumer_id: consumer_id,
299297
provider_id: provider_id,
300298
sha: sha,
301-
content: json_content
302-
)
303-
pact_version.save
299+
content: json_content,
300+
created_at: Sequel.datetime_class.now
301+
).upsert
304302
end
305303

306304
def find_all_database_versions_between(consumer_name, options, base_class = LatestPactPublicationsByConsumerVersion)

lib/pact_broker/repositories/helpers.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def upsert row, unique_key_names, columns_to_update = nil
5151
where(key).update(row)
5252
end
5353
end
54-
model.find(row.select{ |key, _| unique_key_names.include?(key)} )
54+
model.where(row.select{ |key, _| unique_key_names.include?(key)}).single_record
5555
end
5656
end
5757
end

spec/lib/pact_broker/pacts/repository_spec.rb

+11
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ module Pacts
8888
it "reuses the same PactVersion to save room" do
8989
expect { subject }.to_not change{ PactVersion.count }
9090
end
91+
92+
context "when there is a race condition and the pact version gets created by another request in between attempting to find and create" do
93+
before do
94+
allow(PactVersion).to receive(:find).and_return(nil)
95+
end
96+
97+
it "doesn't blow up" do
98+
expect(PactVersion).to receive(:find)
99+
subject
100+
end
101+
end
91102
end
92103

93104
context "when base_equality_only_on_content_that_affects_verification_results is true" do

0 commit comments

Comments
 (0)