Commit c18e47b4 authored by James Lopez's avatar James Lopez

Merge branch '213777-fix-stale-cache-bug' into 'master'

Fix ES rollout stale cache bug

See merge request gitlab-org/gitlab!29233
parents b7ac0f54 bcf42d85
...@@ -27,6 +27,7 @@ class ElasticsearchIndexedNamespace < ApplicationRecord ...@@ -27,6 +27,7 @@ class ElasticsearchIndexedNamespace < ApplicationRecord
end end
def self.drop_limited_ids_cache! def self.drop_limited_ids_cache!
# To prevent stale cache we also drop ElasticsearchIndexedProject cache since it uses ElasticsearchIndexedNamespace
ElasticsearchIndexedProject.drop_limited_ids_cache! ElasticsearchIndexedProject.drop_limited_ids_cache!
super super
end end
...@@ -56,6 +57,8 @@ class ElasticsearchIndexedNamespace < ApplicationRecord ...@@ -56,6 +57,8 @@ class ElasticsearchIndexedNamespace < ApplicationRecord
ElasticNamespaceIndexerWorker.bulk_perform_async(jobs) # rubocop:disable Scalability/BulkPerformWithContext, CodeReuse/Worker ElasticNamespaceIndexerWorker.bulk_perform_async(jobs) # rubocop:disable Scalability/BulkPerformWithContext, CodeReuse/Worker
end end
drop_limited_ids_cache!
end end
def self.unindex_last_n_namespaces_of_plan(plan, number_of_namespaces) def self.unindex_last_n_namespaces_of_plan(plan, number_of_namespaces)
...@@ -73,6 +76,8 @@ class ElasticsearchIndexedNamespace < ApplicationRecord ...@@ -73,6 +76,8 @@ class ElasticsearchIndexedNamespace < ApplicationRecord
ElasticNamespaceIndexerWorker.bulk_perform_async(jobs) # rubocop:disable Scalability/BulkPerformWithContext, CodeReuse/Worker ElasticNamespaceIndexerWorker.bulk_perform_async(jobs) # rubocop:disable Scalability/BulkPerformWithContext, CodeReuse/Worker
end end
drop_limited_ids_cache!
end end
private private
......
---
title: Fix Elasticsearch rollout stale cache bug
merge_request: 29233
author:
type: fixed
...@@ -39,7 +39,7 @@ describe ElasticsearchIndexedNamespace do ...@@ -39,7 +39,7 @@ describe ElasticsearchIndexedNamespace do
end end
end end
context 'with plans' do context 'with plans', :use_clean_rails_redis_caching do
Plan::PAID_HOSTED_PLANS.each do |plan| Plan::PAID_HOSTED_PLANS.each do |plan|
plan_factory = "#{plan}_plan" plan_factory = "#{plan}_plan"
let_it_be(plan_factory) { create(plan_factory) } let_it_be(plan_factory) { create(plan_factory) }
...@@ -54,8 +54,11 @@ describe ElasticsearchIndexedNamespace do ...@@ -54,8 +54,11 @@ describe ElasticsearchIndexedNamespace do
stub_ee_application_setting(elasticsearch_indexing: false) stub_ee_application_setting(elasticsearch_indexing: false)
end end
def get_indexed_namespaces def expect_indexed_namespaces_to_match(array)
described_class.order(:created_at).pluck(:namespace_id) ids = described_class.order(:created_at).pluck(:namespace_id)
expect(ids).to eq(array)
expect(ids).to match_array(described_class.limited_ids_cached)
end end
def expect_queue_to_contain(*args) def expect_queue_to_contain(*args)
...@@ -66,21 +69,23 @@ describe ElasticsearchIndexedNamespace do ...@@ -66,21 +69,23 @@ describe ElasticsearchIndexedNamespace do
describe '.index_first_n_namespaces_of_plan' do describe '.index_first_n_namespaces_of_plan' do
it 'creates records, scoped by plan and ordered by namespace id' do it 'creates records, scoped by plan and ordered by namespace id' do
expect(ElasticsearchIndexedNamespace).to receive(:drop_limited_ids_cache!).and_call_original.exactly(3).times
ids = namespaces.map(&:id) ids = namespaces.map(&:id)
described_class.index_first_n_namespaces_of_plan('gold', 1) described_class.index_first_n_namespaces_of_plan('gold', 1)
expect(get_indexed_namespaces).to eq([ids[0]]) expect_indexed_namespaces_to_match([ids[0]])
expect_queue_to_contain(ids[0], "index") expect_queue_to_contain(ids[0], "index")
described_class.index_first_n_namespaces_of_plan('gold', 2) described_class.index_first_n_namespaces_of_plan('gold', 2)
expect(get_indexed_namespaces).to eq([ids[0], ids[2]]) expect_indexed_namespaces_to_match([ids[0], ids[2]])
expect_queue_to_contain(ids[2], "index") expect_queue_to_contain(ids[2], "index")
described_class.index_first_n_namespaces_of_plan('silver', 1) described_class.index_first_n_namespaces_of_plan('silver', 1)
expect(get_indexed_namespaces).to eq([ids[0], ids[2], ids[1]]) expect_indexed_namespaces_to_match([ids[0], ids[2], ids[1]])
expect_queue_to_contain(ids[1], "index") expect_queue_to_contain(ids[1], "index")
end end
end end
...@@ -92,23 +97,26 @@ describe ElasticsearchIndexedNamespace do ...@@ -92,23 +97,26 @@ describe ElasticsearchIndexedNamespace do
end end
it 'creates records, scoped by plan and ordered by namespace id' do it 'creates records, scoped by plan and ordered by namespace id' do
expect(ElasticsearchIndexedNamespace).to receive(:drop_limited_ids_cache!).and_call_original.exactly(3).times
ids = namespaces.map(&:id) ids = namespaces.map(&:id)
expect(get_indexed_namespaces).to contain_exactly(ids[0], ids[2], ids[1]) expect_indexed_namespaces_to_match([ids[0], ids[2], ids[1]])
described_class.unindex_last_n_namespaces_of_plan('gold', 1) described_class.unindex_last_n_namespaces_of_plan('gold', 1)
expect(get_indexed_namespaces).to contain_exactly(ids[0], ids[1]) expect_indexed_namespaces_to_match([ids[0], ids[1]])
expect_queue_to_contain(ids[2], "delete") expect_queue_to_contain(ids[2], "delete")
described_class.unindex_last_n_namespaces_of_plan('silver', 1) described_class.unindex_last_n_namespaces_of_plan('silver', 1)
expect(get_indexed_namespaces).to contain_exactly(ids[0]) expect_indexed_namespaces_to_match([ids[0]])
expect_queue_to_contain(ids[1], "delete") expect_queue_to_contain(ids[1], "delete")
described_class.unindex_last_n_namespaces_of_plan('gold', 1) described_class.unindex_last_n_namespaces_of_plan('gold', 1)
expect(get_indexed_namespaces).to be_empty expect_indexed_namespaces_to_match([])
expect_queue_to_contain(ids[0], "delete") expect_queue_to_contain(ids[0], "delete")
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment