Merge branch '9903-geo-selective-sync-by-namespace-is-broken' into 'master'

Fix GitLab::JsonCache when reading a persisted entry back from the cache

See merge request gitlab-org/gitlab-ce!25587
This commit is contained in:
Stan Hu 2019-03-01 17:02:56 +00:00
commit adf71cfa75
2 changed files with 42 additions and 2 deletions

View file

@ -71,7 +71,21 @@ module Gitlab
end
def parse_entry(raw, klass)
klass.new(raw) if valid_entry?(raw, klass)
return unless valid_entry?(raw, klass)
return klass.new(raw) unless klass.ancestors.include?(ActiveRecord::Base)
# When the cached value is a persisted instance of ActiveRecord::Base in
# some cases a relation can return an empty collection becauses scope.none!
# is being applied on ActiveRecord::Associations::CollectionAssociation#scope
# when the new_record? method incorrectly returns false.
#
# See https://gitlab.com/gitlab-org/gitlab-ee/issues/9903#note_145329964
attributes = klass.attributes_builder.build_from_database(raw, {})
klass.allocate.init_with("attributes" => attributes, "new_record" => new_record?(raw, klass))
end
def new_record?(raw, klass)
raw.fetch(klass.primary_key, nil).blank?
end
def valid_entry?(raw, klass)

View file

@ -297,13 +297,39 @@ describe Gitlab::JsonCache do
expect(result).to eq(broadcast_message)
end
context 'when the cached value is an instance of ActiveRecord::Base' do
it 'returns a persisted record when id is set' do
backend.write(expanded_key, broadcast_message.to_json)
result = cache.fetch(key, as: BroadcastMessage) { 'block result' }
expect(result).to be_persisted
end
it 'returns a new record when id is nil' do
backend.write(expanded_key, build(:broadcast_message).to_json)
result = cache.fetch(key, as: BroadcastMessage) { 'block result' }
expect(result).to be_new_record
end
it 'returns a new record when id is missing' do
backend.write(expanded_key, build(:broadcast_message).attributes.except('id').to_json)
result = cache.fetch(key, as: BroadcastMessage) { 'block result' }
expect(result).to be_new_record
end
end
it "returns the result of the block when 'as' option is nil" do
result = cache.fetch(key, as: nil) { 'block result' }
expect(result).to eq('block result')
end
it "returns the result of the block when 'as' option is not informed" do
it "returns the result of the block when 'as' option is missing" do
result = cache.fetch(key) { 'block result' }
expect(result).to eq('block result')