Commit 52bfda7f authored by Sean McGivern's avatar Sean McGivern

Merge branch '292861-github-importer-automatically-refresh-import-status' into 'master'

Expire relevant ETag caches for importers

See merge request gitlab-org/gitlab!83849
parents 9c75fcfb cb9f863e
...@@ -70,7 +70,7 @@ class Import::BaseController < ApplicationController ...@@ -70,7 +70,7 @@ class Import::BaseController < ApplicationController
end end
def already_added_projects def already_added_projects
@already_added_projects ||= filtered(find_already_added_projects(provider_name)) @already_added_projects ||= find_already_added_projects(provider_name)
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
......
...@@ -6,6 +6,8 @@ class ProjectImportState < ApplicationRecord ...@@ -6,6 +6,8 @@ class ProjectImportState < ApplicationRecord
self.table_name = "project_mirror_data" self.table_name = "project_mirror_data"
after_commit :expire_etag_cache
belongs_to :project, inverse_of: :import_state belongs_to :project, inverse_of: :import_state
validates :project, presence: true validates :project, presence: true
...@@ -76,6 +78,23 @@ class ProjectImportState < ApplicationRecord ...@@ -76,6 +78,23 @@ class ProjectImportState < ApplicationRecord
end end
end end
def expire_etag_cache
if realtime_changes_path
Gitlab::EtagCaching::Store.new.tap do |store|
store.touch(realtime_changes_path)
rescue Gitlab::EtagCaching::Store::InvalidKeyError
# no-op: not every realtime changes endpoint is using etag caching
end
end
end
def realtime_changes_path
Gitlab::Routing.url_helpers.polymorphic_path([:realtime_changes_import, project.import_type.to_sym], format: :json)
rescue NoMethodError
# polymorphic_path throws NoMethodError when no such path exists
nil
end
def relation_hard_failures(limit:) def relation_hard_failures(limit:)
project.import_failures.hard_failures_by_correlation_id(correlation_id).limit(limit) project.import_failures.hard_failures_by_correlation_id(correlation_id).limit(limit)
end end
......
...@@ -8,8 +8,8 @@ RSpec.describe 'Combined registration flow', :js do ...@@ -8,8 +8,8 @@ RSpec.describe 'Combined registration flow', :js do
let(:experiments) { {} } let(:experiments) { {} }
before do before do
# https://gitlab.com/gitlab-org/gitlab/-/issues/338737 # https://gitlab.com/gitlab-org/gitlab/-/issues/340302
stub_const('Gitlab::QueryLimiting::Transaction::THRESHOLD', 250) stub_const('Gitlab::QueryLimiting::Transaction::THRESHOLD', 270)
stub_experiments(experiments) stub_experiments(experiments)
allow(Gitlab).to receive(:com?).and_return(true) allow(Gitlab).to receive(:com?).and_return(true)
sign_in(user) sign_in(user)
......
...@@ -24,6 +24,8 @@ module Gitlab ...@@ -24,6 +24,8 @@ module Gitlab
increment_project_counter(project, object_type, operation, integer) increment_project_counter(project, object_type, operation, integer)
increment_global_counter(object_type, operation, integer) increment_global_counter(object_type, operation, integer)
project.import_state&.expire_etag_cache
end end
def summary(project) def summary(project)
......
...@@ -258,7 +258,9 @@ RSpec.describe Import::GithubController do ...@@ -258,7 +258,9 @@ RSpec.describe Import::GithubController do
context 'when user input contains colons and spaces' do context 'when user input contains colons and spaces' do
before do before do
allow(controller).to receive(:client_repos).and_return([]) allow_next_instance_of(Gitlab::GithubImport::Client) do |client|
allow(client).to receive(:search_repos_by_name).and_return(items: [])
end
end end
it 'sanitizes user input' do it 'sanitizes user input' do
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::GithubImport::ObjectCounter, :clean_gitlab_redis_cache do RSpec.describe Gitlab::GithubImport::ObjectCounter, :clean_gitlab_redis_cache do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project, :import_started, import_type: 'github') }
it 'validates the operation being incremented' do it 'validates the operation being incremented' do
expect { described_class.increment(project, :issue, :unknown) } expect { described_class.increment(project, :issue, :unknown) }
...@@ -49,4 +49,12 @@ RSpec.describe Gitlab::GithubImport::ObjectCounter, :clean_gitlab_redis_cache do ...@@ -49,4 +49,12 @@ RSpec.describe Gitlab::GithubImport::ObjectCounter, :clean_gitlab_redis_cache do
'imported' => {} 'imported' => {}
}) })
end end
it 'expires etag cache of relevant realtime change endpoints on increment' do
expect_next_instance_of(Gitlab::EtagCaching::Store) do |instance|
expect(instance).to receive(:touch).with(Gitlab::Routing.url_helpers.realtime_changes_import_github_path(format: :json))
end
described_class.increment(project, :issue, :fetched)
end
end end
...@@ -101,6 +101,34 @@ RSpec.describe ProjectImportState, type: :model do ...@@ -101,6 +101,34 @@ RSpec.describe ProjectImportState, type: :model do
end end
end end
describe '#expire_etag_cache' do
context 'when project import type has realtime changes endpoint' do
before do
import_state.project.import_type = 'github'
end
it 'expires revelant etag cache' do
expect_next_instance_of(Gitlab::EtagCaching::Store) do |instance|
expect(instance).to receive(:touch).with(Gitlab::Routing.url_helpers.realtime_changes_import_github_path(format: :json))
end
subject.expire_etag_cache
end
end
context 'when project import type does not have realtime changes endpoint' do
before do
import_state.project.import_type = 'jira'
end
it 'does not touch etag caches' do
expect(Gitlab::EtagCaching::Store).not_to receive(:new)
subject.expire_etag_cache
end
end
end
describe 'import state transitions' do describe 'import state transitions' do
context 'state transition: [:started] => [:finished]' do context 'state transition: [:started] => [:finished]' do
let(:after_import_service) { spy(:after_import_service) } let(:after_import_service) { spy(:after_import_service) }
...@@ -178,4 +206,20 @@ RSpec.describe ProjectImportState, type: :model do ...@@ -178,4 +206,20 @@ RSpec.describe ProjectImportState, type: :model do
end end
end end
end end
describe 'callbacks' do
context 'after_commit :expire_etag_cache' do
before do
import_state.project.import_type = 'github'
end
it 'expires etag cache' do
expect_next_instance_of(Gitlab::EtagCaching::Store) do |instance|
expect(instance).to receive(:touch).with(Gitlab::Routing.url_helpers.realtime_changes_import_github_path(format: :json))
end
subject.save!
end
end
end
end end
...@@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ImportDiffNoteWorker do ...@@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ImportDiffNoteWorker do
describe '#import' do describe '#import' do
it 'imports a diff note' do it 'imports a diff note' do
project = double(:project, full_path: 'foo/bar', id: 1) project = double(:project, full_path: 'foo/bar', id: 1, import_state: nil)
client = double(:client) client = double(:client)
importer = double(:importer) importer = double(:importer)
hash = { hash = {
......
...@@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ImportIssueWorker do ...@@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ImportIssueWorker do
describe '#import' do describe '#import' do
it 'imports an issue' do it 'imports an issue' do
project = double(:project, full_path: 'foo/bar', id: 1) project = double(:project, full_path: 'foo/bar', id: 1, import_state: nil)
client = double(:client) client = double(:client)
importer = double(:importer) importer = double(:importer)
hash = { hash = {
......
...@@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ImportNoteWorker do ...@@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ImportNoteWorker do
describe '#import' do describe '#import' do
it 'imports a note' do it 'imports a note' do
project = double(:project, full_path: 'foo/bar', id: 1) project = double(:project, full_path: 'foo/bar', id: 1, import_state: nil)
client = double(:client) client = double(:client)
importer = double(:importer) importer = double(:importer)
hash = { hash = {
......
...@@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ImportPullRequestWorker do ...@@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ImportPullRequestWorker do
describe '#import' do describe '#import' do
it 'imports a pull request' do it 'imports a pull request' do
project = double(:project, full_path: 'foo/bar', id: 1) project = double(:project, full_path: 'foo/bar', id: 1, import_state: nil)
client = double(:client) client = double(:client)
importer = double(:importer) importer = double(:importer)
hash = { hash = {
......
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