Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2017-01-17 00:34:13 +0300
committerYorick Peterse <yorickpeterse@gmail.com>2017-01-17 00:37:48 +0300
commit6f88984b0d935b5c39b063969c14204cf0a62362 (patch)
tree29d3ca6f3aeed57d366e473fee2f2b75ec30be7f /app/services/users
parent142be72a2aa6920fa60cc267737f2e702fdeae12 (diff)
Synchronize all project authorization refreshing
Previously a lease would only be obtained to update data. This could lead to duplicate data being inserted, triggering a UNIQUE constraint error. To work around this we now acquire a lease before performing _any_ project authorization work, releasing it at the very end. Fixes #25987
Diffstat (limited to 'app/services/users')
-rw-r--r--app/services/users/refresh_authorized_projects_service.rb41
1 files changed, 20 insertions, 21 deletions
diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb
index 21ec1bd9e65..2d211d5ebbe 100644
--- a/app/services/users/refresh_authorized_projects_service.rb
+++ b/app/services/users/refresh_authorized_projects_service.rb
@@ -26,8 +26,26 @@ module Users
user.reload
end
- # This method returns the updated User object.
def execute
+ lease_key = "refresh_authorized_projects:#{user.id}"
+ lease = Gitlab::ExclusiveLease.new(lease_key, timeout: LEASE_TIMEOUT)
+
+ until uuid = lease.try_obtain
+ # Keep trying until we obtain the lease. If we don't do so we may end up
+ # not updating the list of authorized projects properly. To prevent
+ # hammering Redis too much we'll wait for a bit between retries.
+ sleep(1)
+ end
+
+ begin
+ execute_without_lease
+ ensure
+ Gitlab::ExclusiveLease.cancel(lease_key, uuid)
+ end
+ end
+
+ # This method returns the updated User object.
+ def execute_without_lease
current = current_authorizations_per_project
fresh = fresh_access_levels_per_project
@@ -47,26 +65,7 @@ module Users
end
end
- update_with_lease(remove, add)
- end
-
- # Updates the list of authorizations using an exclusive lease.
- def update_with_lease(remove = [], add = [])
- lease_key = "refresh_authorized_projects:#{user.id}"
- lease = Gitlab::ExclusiveLease.new(lease_key, timeout: LEASE_TIMEOUT)
-
- until uuid = lease.try_obtain
- # Keep trying until we obtain the lease. If we don't do so we may end up
- # not updating the list of authorized projects properly. To prevent
- # hammering Redis too much we'll wait for a bit between retries.
- sleep(1)
- end
-
- begin
- update_authorizations(remove, add)
- ensure
- Gitlab::ExclusiveLease.cancel(lease_key, uuid)
- end
+ update_authorizations(remove, add)
end
# Updates the list of authorizations for the current user.