Merge branch 'feature/migrate-wiki-write-page-to-gitaly' into 'master'

Migrate Gitlab::Git::Wiki#write_page to Gitaly

Closes gitaly#638

See merge request gitlab-org/gitlab-ce!14870
This commit is contained in:
Sean McGivern 2017-10-18 11:13:50 +00:00
commit ed194a6d4a
6 changed files with 113 additions and 39 deletions

View file

@ -1 +1 @@
0.47.0
0.48.0

View file

@ -398,7 +398,7 @@ group :ed25519 do
end
# Gitaly GRPC client
gem 'gitaly-proto', '~> 0.42.0', require: 'gitaly'
gem 'gitaly-proto', '~> 0.45.0', require: 'gitaly'
gem 'toml-rb', '~> 0.3.15', require: false

View file

@ -273,7 +273,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gherkin-ruby (0.3.2)
gitaly-proto (0.42.0)
gitaly-proto (0.45.0)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (4.7.6)
@ -1030,7 +1030,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0)
gitaly-proto (~> 0.42.0)
gitaly-proto (~> 0.45.0)
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.6.2)

View file

@ -23,14 +23,14 @@ module Gitlab
end
def write_page(name, format, content, commit_details)
assert_type!(format, Symbol)
assert_type!(commit_details, CommitDetails)
gollum_wiki.write_page(name, format, content, commit_details.to_h)
nil
rescue Gollum::DuplicatePageError => e
raise Gitlab::Git::Wiki::DuplicatePageError, e.message
@repository.gitaly_migrate(:wiki_write_page) do |is_enabled|
if is_enabled
gitaly_write_page(name, format, content, commit_details)
gollum_wiki.clear_cache
else
gollum_write_page(name, format, content, commit_details)
end
end
end
def delete_page(page_path, commit_details)
@ -110,6 +110,25 @@ module Gitlab
raise ArgumentError, "expected a #{klass}, got #{object.inspect}"
end
end
def gitaly_wiki_client
@gitaly_wiki_client ||= Gitlab::GitalyClient::WikiService.new(@repository)
end
def gollum_write_page(name, format, content, commit_details)
assert_type!(format, Symbol)
assert_type!(commit_details, CommitDetails)
gollum_wiki.write_page(name, format, content, commit_details.to_h)
nil
rescue Gollum::DuplicatePageError => e
raise Gitlab::Git::Wiki::DuplicatePageError, e.message
end
def gitaly_write_page(name, format, content, commit_details)
gitaly_wiki_client.write_page(name, format, content, commit_details)
end
end
end
end

View file

@ -0,0 +1,45 @@
require 'stringio'
module Gitlab
module GitalyClient
class WikiService
MAX_MSG_SIZE = 128.kilobytes.freeze
def initialize(repository)
@gitaly_repo = repository.gitaly_repository
@repository = repository
end
def write_page(name, format, content, commit_details)
request = Gitaly::WikiWritePageRequest.new(
repository: @gitaly_repo,
name: GitalyClient.encode(name),
format: format.to_s,
commit_details: Gitaly::WikiCommitDetails.new(
name: GitalyClient.encode(commit_details.name),
email: GitalyClient.encode(commit_details.email),
message: GitalyClient.encode(commit_details.message)
)
)
strio = StringIO.new(content)
enum = Enumerator.new do |y|
until strio.eof?
chunk = strio.read(MAX_MSG_SIZE)
request.content = GitalyClient.encode(chunk)
y.yield request
request = Gitaly::WikiWritePageRequest.new
end
end
response = GitalyClient.call(@repository.storage, :wiki_service, :wiki_write_page, enum)
if error = response.duplicate_error.presence
raise Gitlab::Git::Wiki::DuplicatePageError, error
end
end
end
end
end

View file

@ -180,37 +180,47 @@ describe ProjectWiki do
end
describe "#create_page" do
after do
destroy_page(subject.pages.first.page)
shared_examples 'creating a wiki page' do
after do
destroy_page(subject.pages.first.page)
end
it "creates a new wiki page" do
expect(subject.create_page("test page", "this is content")).not_to eq(false)
expect(subject.pages.count).to eq(1)
end
it "returns false when a duplicate page exists" do
subject.create_page("test page", "content")
expect(subject.create_page("test page", "content")).to eq(false)
end
it "stores an error message when a duplicate page exists" do
2.times { subject.create_page("test page", "content") }
expect(subject.error_message).to match(/Duplicate page:/)
end
it "sets the correct commit message" do
subject.create_page("test page", "some content", :markdown, "commit message")
expect(subject.pages.first.page.version.message).to eq("commit message")
end
it 'updates project activity' do
subject.create_page('Test Page', 'This is content')
project.reload
expect(project.last_activity_at).to be_within(1.minute).of(Time.now)
expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now)
end
end
it "creates a new wiki page" do
expect(subject.create_page("test page", "this is content")).not_to eq(false)
expect(subject.pages.count).to eq(1)
context 'when Gitaly wiki_write_page is enabled' do
it_behaves_like 'creating a wiki page'
end
it "returns false when a duplicate page exists" do
subject.create_page("test page", "content")
expect(subject.create_page("test page", "content")).to eq(false)
end
it "stores an error message when a duplicate page exists" do
2.times { subject.create_page("test page", "content") }
expect(subject.error_message).to match(/Duplicate page:/)
end
it "sets the correct commit message" do
subject.create_page("test page", "some content", :markdown, "commit message")
expect(subject.pages.first.page.version.message).to eq("commit message")
end
it 'updates project activity' do
subject.create_page('Test Page', 'This is content')
project.reload
expect(project.last_activity_at).to be_within(1.minute).of(Time.now)
expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now)
context 'when Gitaly wiki_write_page is disabled', :skip_gitaly_mock do
it_behaves_like 'creating a wiki page'
end
end