Commit b5d77d90 authored by Dmitry Gruzd's avatar Dmitry Gruzd

Remove cached/memoized ES helper

Any Elasticsearch admin setting changes will not be updated for the
Elasticsearch migrations until sidekiq is restarted. For example
changing the URL or other settings will keep using the old URL in the
migration until sidekiq is restarted. This change fixes this problem by
removing class level memoization of Gitlab::Elastic::Helper
parent d921fc2f
---
title: Remove cached/memoized ES helper
merge_request: 51310
author:
type: fixed
...@@ -38,7 +38,7 @@ module Gitlab ...@@ -38,7 +38,7 @@ module Gitlab
end end
def default def default
@default ||= self.new self.new
end end
end end
......
...@@ -4,14 +4,16 @@ require 'spec_helper' ...@@ -4,14 +4,16 @@ require 'spec_helper'
RSpec.describe Admin::ElasticsearchController do RSpec.describe Admin::ElasticsearchController do
let(:admin) { create(:admin) } let(:admin) { create(:admin) }
let(:helper) { Gitlab::Elastic::Helper.new }
describe 'POST #enqueue_index' do describe 'POST #enqueue_index' do
before do before do
sign_in(admin) sign_in(admin)
allow(Gitlab::Elastic::Helper).to receive(:default).and_return(helper)
end end
it 'starts indexing' do it 'starts indexing' do
expect(Gitlab::Elastic::Helper.default).to(receive(:index_exists?)).and_return(true) expect(helper).to(receive(:index_exists?)).and_return(true)
expect_next_instance_of(::Elastic::IndexProjectsService) do |service| expect_next_instance_of(::Elastic::IndexProjectsService) do |service|
expect(service).to receive(:execute) expect(service).to receive(:execute)
end end
......
...@@ -39,6 +39,12 @@ RSpec.describe Gitlab::Elastic::Helper do ...@@ -39,6 +39,12 @@ RSpec.describe Gitlab::Elastic::Helper do
end end
end end
describe '.default' do
it 'does not cache the value' do
expect(described_class.default.object_id).not_to eq(described_class.default.object_id)
end
end
describe '#default_mappings' do describe '#default_mappings' do
it 'has only one type' do it 'has only one type' do
expect(helper.default_mappings.keys).to match_array %i(doc) expect(helper.default_mappings.keys).to match_array %i(doc)
......
...@@ -3,6 +3,12 @@ ...@@ -3,6 +3,12 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Elastic::ReindexingTask, type: :model do RSpec.describe Elastic::ReindexingTask, type: :model do
let(:helper) { Gitlab::Elastic::Helper.new }
before do
allow(Gitlab::Elastic::Helper).to receive(:default).and_return(helper)
end
describe 'relations' do describe 'relations' do
it { is_expected.to have_many(:subtasks) } it { is_expected.to have_many(:subtasks) }
end end
...@@ -32,11 +38,11 @@ RSpec.describe Elastic::ReindexingTask, type: :model do ...@@ -32,11 +38,11 @@ RSpec.describe Elastic::ReindexingTask, type: :model do
it 'deletes the correct indices' do it 'deletes the correct indices' do
other_tasks.each do |task| other_tasks.each do |task|
expect(Gitlab::Elastic::Helper.default).not_to receive(:delete_index).with(index_name: task.subtasks.first.index_name_from) expect(helper).not_to receive(:delete_index).with(index_name: task.subtasks.first.index_name_from)
end end
tasks_for_deletion.each do |task| tasks_for_deletion.each do |task|
expect(Gitlab::Elastic::Helper.default).to receive(:delete_index).with(index_name: task.subtasks.first.index_name_from).and_return(true) expect(helper).to receive(:delete_index).with(index_name: task.subtasks.first.index_name_from).and_return(true)
end end
described_class.drop_old_indices! described_class.drop_old_indices!
......
...@@ -35,13 +35,19 @@ RSpec.describe ApplicationSettings::UpdateService do ...@@ -35,13 +35,19 @@ RSpec.describe ApplicationSettings::UpdateService do
end end
context 'elasticsearch_indexing update' do context 'elasticsearch_indexing update' do
let(:helper) { Gitlab::Elastic::Helper.new }
before do
allow(Gitlab::Elastic::Helper).to receive(:default).and_return(helper)
end
context 'index creation' do context 'index creation' do
let(:opts) { { elasticsearch_indexing: true } } let(:opts) { { elasticsearch_indexing: true } }
context 'when index exists' do context 'when index exists' do
it 'skips creating a new index' do it 'skips creating a new index' do
expect(Gitlab::Elastic::Helper.default).to(receive(:index_exists?)).and_return(true) expect(helper).to(receive(:index_exists?)).and_return(true)
expect(Gitlab::Elastic::Helper.default).not_to(receive(:create_empty_index)) expect(helper).not_to(receive(:create_empty_index))
service.execute service.execute
end end
...@@ -49,8 +55,8 @@ RSpec.describe ApplicationSettings::UpdateService do ...@@ -49,8 +55,8 @@ RSpec.describe ApplicationSettings::UpdateService do
context 'when index does not exist' do context 'when index does not exist' do
it 'creates a new index' do it 'creates a new index' do
expect(Gitlab::Elastic::Helper.default).to(receive(:index_exists?)).and_return(false) expect(helper).to(receive(:index_exists?)).and_return(false)
expect(Gitlab::Elastic::Helper.default).to(receive(:create_empty_index)) expect(helper).to(receive(:create_empty_index))
service.execute service.execute
end end
......
...@@ -5,11 +5,17 @@ require 'spec_helper' ...@@ -5,11 +5,17 @@ require 'spec_helper'
RSpec.describe Elastic::ClusterReindexingService, :elastic do RSpec.describe Elastic::ClusterReindexingService, :elastic do
subject { described_class.new } subject { described_class.new }
let(:helper) { Gitlab::Elastic::Helper.new }
before do
allow(Gitlab::Elastic::Helper).to receive(:default).and_return(helper)
end
context 'state: initial' do context 'state: initial' do
let(:task) { create(:elastic_reindexing_task, state: :initial) } let(:task) { create(:elastic_reindexing_task, state: :initial) }
it 'aborts if the main index does not use aliases' do it 'aborts if the main index does not use aliases' do
allow(Gitlab::Elastic::Helper.default).to receive(:alias_exists?).and_return(false) allow(helper).to receive(:alias_exists?).and_return(false)
expect { subject.execute }.to change { task.reload.state }.from('initial').to('failure') expect { subject.execute }.to change { task.reload.state }.from('initial').to('failure')
expect(task.reload.error_message).to match(/use aliases/) expect(task.reload.error_message).to match(/use aliases/)
...@@ -23,8 +29,8 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do ...@@ -23,8 +29,8 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do
end end
it 'errors when there is not enough space' do it 'errors when there is not enough space' do
allow(Gitlab::Elastic::Helper.default).to receive(:index_size_bytes).and_return(100.megabytes) allow(helper).to receive(:index_size_bytes).and_return(100.megabytes)
allow(Gitlab::Elastic::Helper.default).to receive(:cluster_free_size_bytes).and_return(30.megabytes) allow(helper).to receive(:cluster_free_size_bytes).and_return(30.megabytes)
expect { subject.execute }.to change { task.reload.state }.from('initial').to('failure') expect { subject.execute }.to change { task.reload.state }.from('initial').to('failure')
expect(task.reload.error_message).to match(/storage available/) expect(task.reload.error_message).to match(/storage available/)
...@@ -43,10 +49,10 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do ...@@ -43,10 +49,10 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do
it 'triggers reindexing' do it 'triggers reindexing' do
task = create(:elastic_reindexing_task, state: :indexing_paused) task = create(:elastic_reindexing_task, state: :indexing_paused)
allow(Gitlab::Elastic::Helper.default).to receive(:create_empty_index).and_return('new_index_name' => 'new_index') allow(helper).to receive(:create_empty_index).and_return('new_index_name' => 'new_index')
allow(Gitlab::Elastic::Helper.default).to receive(:create_standalone_indices).and_return('new_issues_name' => 'new_issues') allow(helper).to receive(:create_standalone_indices).and_return('new_issues_name' => 'new_issues')
allow(Gitlab::Elastic::Helper.default).to receive(:reindex).with(from: anything, to: 'new_index_name').and_return('task_id_1') allow(helper).to receive(:reindex).with(from: anything, to: 'new_index_name').and_return('task_id_1')
allow(Gitlab::Elastic::Helper.default).to receive(:reindex).with(from: anything, to: 'new_issues_name').and_return('task_id_2') allow(helper).to receive(:reindex).with(from: anything, to: 'new_issues_name').and_return('task_id_2')
expect { subject.execute }.to change { task.reload.state }.from('indexing_paused').to('reindexing') expect { subject.execute }.to change { task.reload.state }.from('indexing_paused').to('reindexing')
...@@ -72,13 +78,13 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do ...@@ -72,13 +78,13 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do
end end
before do before do
allow(Gitlab::Elastic::Helper.default).to receive(:task_status).and_return({ 'completed' => true }) allow(helper).to receive(:task_status).and_return({ 'completed' => true })
allow(Gitlab::Elastic::Helper.default).to receive(:refresh_index).and_return(true) allow(helper).to receive(:refresh_index).and_return(true)
end end
context 'errors are raised' do context 'errors are raised' do
before do before do
allow(Gitlab::Elastic::Helper.default).to receive(:documents_count).with(index_name: subtask.index_name_to).and_return(subtask.reload.documents_count * 2) allow(helper).to receive(:documents_count).with(index_name: subtask.index_name_to).and_return(subtask.reload.documents_count * 2)
end end
it 'errors if documents count is different' do it 'errors if documents count is different' do
...@@ -87,14 +93,14 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do ...@@ -87,14 +93,14 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do
end end
it 'errors if reindexing is failed' do it 'errors if reindexing is failed' do
allow(Gitlab::Elastic::Helper.default).to receive(:task_status).and_return({ 'completed' => true, 'error' => { 'type' => 'search_phase_execution_exception' } }) allow(helper).to receive(:task_status).and_return({ 'completed' => true, 'error' => { 'type' => 'search_phase_execution_exception' } })
expect { subject.execute }.to change { task.reload.state }.from('reindexing').to('failure') expect { subject.execute }.to change { task.reload.state }.from('reindexing').to('failure')
expect(task.reload.error_message).to match(/has failed with/) expect(task.reload.error_message).to match(/has failed with/)
end end
it 'errors if task is not found' do it 'errors if task is not found' do
allow(Gitlab::Elastic::Helper.default).to receive(:task_status).and_raise(Elasticsearch::Transport::Transport::Errors::NotFound) allow(helper).to receive(:task_status).and_raise(Elasticsearch::Transport::Transport::Errors::NotFound)
expect { subject.execute }.to change { task.reload.state }.from('reindexing').to('failure') expect { subject.execute }.to change { task.reload.state }.from('reindexing').to('failure')
expect(task.reload.error_message).to match(/couldn't load task status/i) expect(task.reload.error_message).to match(/couldn't load task status/i)
...@@ -103,12 +109,12 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do ...@@ -103,12 +109,12 @@ RSpec.describe Elastic::ClusterReindexingService, :elastic do
context 'task finishes correctly' do context 'task finishes correctly' do
before do before do
allow(Gitlab::Elastic::Helper.default).to receive(:documents_count).with(index_name: subtask.index_name_to).and_return(subtask.reload.documents_count) allow(helper).to receive(:documents_count).with(index_name: subtask.index_name_to).and_return(subtask.reload.documents_count)
end end
it 'launches all state steps' do it 'launches all state steps' do
expect(Gitlab::Elastic::Helper.default).to receive(:update_settings).with(index_name: subtask.index_name_to, settings: expected_default_settings) expect(helper).to receive(:update_settings).with(index_name: subtask.index_name_to, settings: expected_default_settings)
expect(Gitlab::Elastic::Helper.default).to receive(:switch_alias).with(to: subtask.index_name_to, from: subtask.index_name_from, alias_name: subtask.alias_name) expect(helper).to receive(:switch_alias).with(to: subtask.index_name_to, from: subtask.index_name_from, alias_name: subtask.alias_name)
expect(Gitlab::CurrentSettings).to receive(:update!).with(elasticsearch_pause_indexing: false) expect(Gitlab::CurrentSettings).to receive(:update!).with(elasticsearch_pause_indexing: false)
expect { subject.execute }.to change { task.reload.state }.from('reindexing').to('success') expect { subject.execute }.to change { task.reload.state }.from('reindexing').to('success')
......
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