Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
39298575
Commit
39298575
authored
7 years ago
by
Tiago Botelho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds exclusive lease to Git garbage collect worker.
parent
21935d85
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
154 additions
and
24 deletions
+154
-24
app/workers/git_garbage_collect_worker.rb
app/workers/git_garbage_collect_worker.rb
+32
-2
lib/gitlab/exclusive_lease.rb
lib/gitlab/exclusive_lease.rb
+8
-2
spec/lib/gitlab/exclusive_lease_spec.rb
spec/lib/gitlab/exclusive_lease_spec.rb
+12
-0
spec/services/projects/housekeeping_service_spec.rb
spec/services/projects/housekeeping_service_spec.rb
+1
-0
spec/workers/git_garbage_collect_worker_spec.rb
spec/workers/git_garbage_collect_worker_spec.rb
+101
-20
No files found.
app/workers/git_garbage_collect_worker.rb
View file @
39298575
...
...
@@ -5,6 +5,9 @@ class GitGarbageCollectWorker
sidekiq_options
retry:
false
# Timeout set to 24h
LEASE_TIMEOUT
=
86400
GITALY_MIGRATED_TASKS
=
{
gc: :garbage_collect
,
full_repack: :repack_full
,
...
...
@@ -13,8 +16,19 @@ class GitGarbageCollectWorker
def
perform
(
project_id
,
task
=
:gc
,
lease_key
=
nil
,
lease_uuid
=
nil
)
project
=
Project
.
find
(
project_id
)
task
=
task
.
to_sym
active_uuid
=
get_lease_uuid
(
lease_key
)
if
active_uuid
return
unless
active_uuid
==
lease_uuid
renew_lease
(
lease_key
,
active_uuid
)
else
lease_uuid
=
try_obtain_lease
(
lease_key
)
return
unless
lease_uuid
end
task
=
task
.
to_sym
cmd
=
command
(
task
)
repo_path
=
project
.
repository
.
path_to_repo
description
=
"'
#{
cmd
.
join
(
' '
)
}
' in
#{
repo_path
}
"
...
...
@@ -33,11 +47,27 @@ class GitGarbageCollectWorker
# Refresh the branch cache in case garbage collection caused a ref lookup to fail
flush_ref_caches
(
project
)
if
task
==
:gc
ensure
Gitlab
::
ExclusiveLease
.
cancel
(
lease_key
,
lease_uuid
)
if
lease_key
.
present?
&&
lease_uuid
.
present?
cancel_lease
(
lease_key
,
lease_uuid
)
if
lease_key
.
present?
&&
lease_uuid
.
present?
end
private
def
try_obtain_lease
(
key
)
::
Gitlab
::
ExclusiveLease
.
new
(
key
,
timeout:
LEASE_TIMEOUT
).
try_obtain
end
def
renew_lease
(
key
,
uuid
)
::
Gitlab
::
ExclusiveLease
.
new
(
key
,
uuid:
uuid
,
timeout:
LEASE_TIMEOUT
).
renew
end
def
cancel_lease
(
key
,
uuid
)
::
Gitlab
::
ExclusiveLease
.
cancel
(
key
,
uuid
)
end
def
get_lease_uuid
(
key
)
::
Gitlab
::
ExclusiveLease
.
get_uuid
(
key
)
end
## `repository` has to be a Gitlab::Git::Repository
def
gitaly_call
(
task
,
repository
)
client
=
Gitlab
::
GitalyClient
::
RepositoryService
.
new
(
repository
)
...
...
This diff is collapsed.
Click to expand it.
lib/gitlab/exclusive_lease.rb
View file @
39298575
...
...
@@ -25,6 +25,12 @@ module Gitlab
end
EOS
def
self
.
get_uuid
(
key
)
Gitlab
::
Redis
::
SharedState
.
with
do
|
redis
|
redis
.
get
(
redis_shared_state_key
(
key
))
||
false
end
end
def
self
.
cancel
(
key
,
uuid
)
Gitlab
::
Redis
::
SharedState
.
with
do
|
redis
|
redis
.
eval
(
LUA_CANCEL_SCRIPT
,
keys:
[
redis_shared_state_key
(
key
)],
argv:
[
uuid
])
...
...
@@ -35,10 +41,10 @@ module Gitlab
"gitlab:exclusive_lease:
#{
key
}
"
end
def
initialize
(
key
,
timeout
:)
def
initialize
(
key
,
uuid:
nil
,
timeout
:)
@redis_shared_state_key
=
self
.
class
.
redis_shared_state_key
(
key
)
@timeout
=
timeout
@uuid
=
SecureRandom
.
uuid
@uuid
=
uuid
||
SecureRandom
.
uuid
end
# Try to obtain the lease. Return lease UUID on success,
...
...
This diff is collapsed.
Click to expand it.
spec/lib/gitlab/exclusive_lease_spec.rb
View file @
39298575
...
...
@@ -47,6 +47,18 @@ describe Gitlab::ExclusiveLease, :clean_gitlab_redis_shared_state do
end
end
describe
'.get_uuid'
do
it
'gets the uuid if lease with the key associated exists'
do
uuid
=
described_class
.
new
(
unique_key
,
timeout:
3600
).
try_obtain
expect
(
described_class
.
get_uuid
(
unique_key
)).
to
eq
(
uuid
)
end
it
'returns false if the lease does not exist'
do
expect
(
described_class
.
get_uuid
(
unique_key
)).
to
be
false
end
end
describe
'.cancel'
do
it
'can cancel a lease'
do
uuid
=
new_lease
(
unique_key
)
...
...
This diff is collapsed.
Click to expand it.
spec/services/projects/housekeeping_service_spec.rb
View file @
39298575
...
...
@@ -20,6 +20,7 @@ describe Projects::HousekeepingService do
expect
(
GitGarbageCollectWorker
).
to
receive
(
:perform_async
).
with
(
project
.
id
,
:the_task
,
:the_lease_key
,
:the_uuid
)
subject
.
execute
expect
(
project
.
reload
.
pushes_since_gc
).
to
eq
(
0
)
end
...
...
This diff is collapsed.
Click to expand it.
spec/workers/git_garbage_collect_worker_spec.rb
View file @
39298575
...
...
@@ -5,11 +5,65 @@ require 'spec_helper'
describe
GitGarbageCollectWorker
do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:shell
)
{
Gitlab
::
Shell
.
new
}
let!
(
:lease_uuid
)
{
SecureRandom
.
uuid
}
let!
(
:lease_key
)
{
"project_housekeeping:
#{
project
.
id
}
"
}
subject
{
described_class
.
new
}
describe
"#perform"
do
shared_examples
'flushing ref caches'
do
|
gitaly
|
context
'with active lease_uuid'
do
before
do
allow
(
subject
).
to
receive
(
:get_lease_uuid
).
and_return
(
lease_uuid
)
end
it
"flushes ref caches when the task if 'gc'"
do
expect
(
subject
).
to
receive
(
:renew_lease
).
with
(
lease_key
,
lease_uuid
).
and_call_original
expect
(
subject
).
to
receive
(
:command
).
with
(
:gc
).
and_return
([
:the
,
:command
])
if
gitaly
expect_any_instance_of
(
Gitlab
::
GitalyClient
::
RepositoryService
).
to
receive
(
:garbage_collect
)
.
and_return
(
nil
)
else
expect
(
Gitlab
::
Popen
).
to
receive
(
:popen
)
.
with
([
:the
,
:command
],
project
.
repository
.
path_to_repo
).
and_return
([
""
,
0
])
end
expect_any_instance_of
(
Repository
).
to
receive
(
:after_create_branch
).
and_call_original
expect_any_instance_of
(
Repository
).
to
receive
(
:branch_names
).
and_call_original
expect_any_instance_of
(
Gitlab
::
Git
::
Repository
).
to
receive
(
:branch_count
).
and_call_original
expect_any_instance_of
(
Gitlab
::
Git
::
Repository
).
to
receive
(
:has_visible_content?
).
and_call_original
subject
.
perform
(
project
.
id
,
:gc
,
lease_key
,
lease_uuid
)
end
end
context
'with different lease than the active one'
do
before
do
allow
(
subject
).
to
receive
(
:get_lease_uuid
).
and_return
(
SecureRandom
.
uuid
)
end
it
'returns silently'
do
expect
(
subject
).
not_to
receive
(
:command
)
expect_any_instance_of
(
Repository
).
not_to
receive
(
:after_create_branch
).
and_call_original
expect_any_instance_of
(
Repository
).
not_to
receive
(
:branch_names
).
and_call_original
expect_any_instance_of
(
Repository
).
not_to
receive
(
:branch_count
).
and_call_original
expect_any_instance_of
(
Repository
).
not_to
receive
(
:has_visible_content?
).
and_call_original
subject
.
perform
(
project
.
id
,
:gc
,
lease_key
,
lease_uuid
)
end
end
context
'with no active lease'
do
before
do
allow
(
subject
).
to
receive
(
:get_lease_uuid
).
and_return
(
false
)
end
context
'when is able to get the lease'
do
before
do
allow
(
subject
).
to
receive
(
:try_obtain_lease
).
and_return
(
SecureRandom
.
uuid
)
end
it
"flushes ref caches when the task if 'gc'"
do
expect
(
subject
).
to
receive
(
:command
).
with
(
:gc
).
and_return
([
:the
,
:command
])
...
...
@@ -30,6 +84,24 @@ describe GitGarbageCollectWorker do
end
end
context
'when no lease can be obtained'
do
before
do
expect
(
subject
).
to
receive
(
:try_obtain_lease
).
and_return
(
false
)
end
it
'returns silently'
do
expect
(
subject
).
not_to
receive
(
:command
)
expect_any_instance_of
(
Repository
).
not_to
receive
(
:after_create_branch
).
and_call_original
expect_any_instance_of
(
Repository
).
not_to
receive
(
:branch_names
).
and_call_original
expect_any_instance_of
(
Repository
).
not_to
receive
(
:branch_count
).
and_call_original
expect_any_instance_of
(
Repository
).
not_to
receive
(
:has_visible_content?
).
and_call_original
subject
.
perform
(
project
.
id
)
end
end
end
end
context
"with Gitaly turned on"
do
it_should_behave_like
'flushing ref caches'
,
true
end
...
...
@@ -39,25 +111,34 @@ describe GitGarbageCollectWorker do
end
context
"repack_full"
do
before
do
expect
(
subject
).
to
receive
(
:get_lease_uuid
).
and_return
(
lease_uuid
)
end
it
"calls Gitaly"
do
expect_any_instance_of
(
Gitlab
::
GitalyClient
::
RepositoryService
).
to
receive
(
:repack_full
)
.
and_return
(
nil
)
subject
.
perform
(
project
.
id
,
:full_repack
)
subject
.
perform
(
project
.
id
,
:full_repack
,
lease_key
,
lease_uuid
)
end
end
context
"repack_incremental"
do
before
do
expect
(
subject
).
to
receive
(
:get_lease_uuid
).
and_return
(
lease_uuid
)
end
it
"calls Gitaly"
do
expect_any_instance_of
(
Gitlab
::
GitalyClient
::
RepositoryService
).
to
receive
(
:repack_incremental
)
.
and_return
(
nil
)
subject
.
perform
(
project
.
id
,
:incremental_repack
)
subject
.
perform
(
project
.
id
,
:incremental_repack
,
lease_key
,
lease_uuid
)
end
end
shared_examples
'gc tasks'
do
before
do
allow
(
subject
).
to
receive
(
:get_lease_uuid
).
and_return
(
lease_uuid
)
allow
(
subject
).
to
receive
(
:bitmaps_enabled?
).
and_return
(
bitmaps_enabled
)
end
...
...
@@ -67,7 +148,7 @@ describe GitGarbageCollectWorker do
expect
(
before_packs
.
count
).
to
be
>=
1
subject
.
perform
(
project
.
id
,
'incremental_repack'
)
subject
.
perform
(
project
.
id
,
'incremental_repack'
,
lease_key
,
lease_uuid
)
after_packs
=
packs
(
project
)
# Exactly one new pack should have been created
...
...
@@ -79,12 +160,12 @@ describe GitGarbageCollectWorker do
it
'full repack consolidates into 1 packfile'
do
create_objects
(
project
)
subject
.
perform
(
project
.
id
,
'incremental_repack'
)
subject
.
perform
(
project
.
id
,
'incremental_repack'
,
lease_key
,
lease_uuid
)
before_packs
=
packs
(
project
)
expect
(
before_packs
.
count
).
to
be
>=
2
subject
.
perform
(
project
.
id
,
'full_repack'
)
subject
.
perform
(
project
.
id
,
'full_repack'
,
lease_key
,
lease_uuid
)
after_packs
=
packs
(
project
)
expect
(
after_packs
.
count
).
to
eq
(
1
)
...
...
@@ -102,7 +183,7 @@ describe GitGarbageCollectWorker do
expect
(
before_packs
.
count
).
to
be
>=
1
subject
.
perform
(
project
.
id
,
'gc'
)
subject
.
perform
(
project
.
id
,
'gc'
,
lease_key
,
lease_uuid
)
after_packed_refs
=
packed_refs
(
project
)
after_packs
=
packs
(
project
)
...
...
This diff is collapsed.
Click to expand it.
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