BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
dcea4501
Commit
dcea4501
authored
Dec 23, 2016
by
Yorick Peterse
Committed by
Dmitriy Zaporozhets
Dec 24, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix parallel renaming of reserved projects
This ensures threads don't re-use the same connection object, and use fewer queries to perform the work.
parent
d72b4042
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
87 additions
and
26 deletions
+87
-26
20161221153951_rename_reserved_project_names.rb
...t_migrate/20161221153951_rename_reserved_project_names.rb
+87
-26
No files found.
db/post_migrate/20161221153951_rename_reserved_project_names.rb
View file @
dcea4501
require
'thread'
class
RenameReservedProjectNames
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
include
Gitlab
::
ShellAdapter
DOWNTIME
=
false
class
Project
<
ActiveRecord
::
Base
;
end
THREAD_COUNT
=
8
KNOWN_PATHS
=
%w(.well-known
all
assets
blame
blob
commits
create
create_dir
edit
files
files
find_file
groups
hooks
issues
logs_tree
merge_requests
new
new
preview
profile
projects
public
raw
repository
robots.txt
s
snippets
teams
tree
u
unsubscribes
update
users
wikis)
def
up
threads
=
reserved_projects
.
each_slice
(
100
).
map
do
|
slice
|
queues
=
Array
.
new
(
THREAD_COUNT
)
{
Queue
.
new
}
start
=
false
threads
=
Array
.
new
(
THREAD_COUNT
)
do
|
index
|
Thread
.
new
do
rename_projects
(
slice
)
queue
=
queues
[
index
]
# Wait until we have input to process.
until
start
;
end
rename_projects
(
queue
.
pop
)
until
queue
.
empty?
end
end
enum
=
queues
.
each
reserved_projects
.
each_slice
(
100
)
do
|
slice
|
begin
queue
=
enum
.
next
rescue
StopIteration
enum
.
rewind
retry
end
queue
<<
slice
end
start
=
true
threads
.
each
(
&
:join
)
end
...
...
@@ -23,18 +84,17 @@ class RenameReservedProjectNames < ActiveRecord::Migration
private
def
reserved_projects
select_all
(
"SELECT p.id, p.path, p.repository_storage, n.path AS namespace_path, n.id AS namespace_id FROM projects p
INNER JOIN namespaces n ON n.id = p.namespace_id
WHERE p.path IN (
'.well-known', 'all', 'assets', 'files', 'groups', 'hooks', 'issues',
'merge_requests', 'new', 'profile', 'projects', 'public', 'repository',
'robots.txt', 's', 'snippets', 'teams', 'u', 'unsubscribes', 'users',
'tree', 'commits', 'wikis', 'new', 'edit', 'create', 'update', 'logs_tree',
'preview', 'blob', 'blame', 'raw', 'files', 'create_dir', 'find_file')"
)
Project
.
unscoped
.
includes
(
:namespace
).
where
(
'EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)'
).
where
(
'projects.path'
=>
KNOWN_PATHS
)
end
def
route_exists?
(
full_path
)
select_all
(
"SELECT id, path FROM routes WHERE path = '
#{
quote_string
(
full_path
)
}
'"
).
present?
quoted_path
=
ActiveRecord
::
Base
.
connection
.
quote_string
(
full_path
)
ActiveRecord
::
Base
.
connection
.
select_all
(
"SELECT id, path FROM routes WHERE path = '
#{
quoted_path
}
'"
).
present?
end
# Adds number to the end of the path that is not taken by other route
...
...
@@ -51,26 +111,27 @@ class RenameReservedProjectNames < ActiveRecord::Migration
end
def
rename_projects
(
projects
)
projects
.
each
do
|
row
|
id
=
row
[
'id'
]
path_was
=
row
[
'path'
]
namespace_path
=
row
[
'namespace_path'
]
projects
.
each
do
|
project
|
next
unless
project
.
namespace
id
=
project
.
id
path_was
=
project
.
path
namespace_path
=
project
.
namespace
.
path
path
=
rename_path
(
namespace_path
,
path_was
)
project
=
Project
.
find_by
(
id:
id
)
begin
# Because project path update is quite complex operation we can't safely
# copy-paste all code from GitLab. As exception we use Rails code here
if
project
&&
project
.
respond_to?
(
:update_attributes
)
&&
project
.
update_attributes
(
path:
path
)
&&
project
.
respond_to?
(
:rename_repo
)
project
.
rename_repo
end
rescue
=>
e
Rails
.
logger
.
error
"Exception when rename project
#{
id
}
:
#{
e
.
message
}
"
project
.
rename_repo
if
rename_project_row
(
project
,
path
)
rescue
Exception
=>
e
# rubocop: disable Lint/RescueException
Rails
.
logger
.
error
"Exception when renaming project
#{
id
}
:
#{
e
.
message
}
"
end
end
end
def
rename_project_row
(
project
,
path
)
project
.
respond_to?
(
:update_attributes
)
&&
project
.
update_attributes
(
path:
path
)
&&
project
.
respond_to?
(
:rename_repo
)
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment