Commit bcf42d85 authored by Dmitry Gruzd's avatar Dmitry Gruzd

Fix ES indexed namespaces stale cache bug

parent c5802dcf
...@@ -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