diff options
author | Douwe Maan <douwe@gitlab.com> | 2016-11-28 03:35:37 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2016-11-28 03:35:37 +0000 |
commit | d2813832615c6baf1f176c39b260b66a702d3e70 (patch) | |
tree | 006d20a5d62ff5f07da50a9260b53ca5298402a5 /app/models | |
parent | d8f75233686fe20bff26599704fbcb235f7bb43b (diff) | |
parent | 92b2c74ce14238c1032bd9faac6d178d25433532 (diff) | |
download | gitlab-ce-d2813832615c6baf1f176c39b260b66a702d3e70.tar.gz |
Merge branch 'refresh-authorizations-with-lease' into 'master'
Refresh project authorizations using a Redis lease
This MR changes `User#refresh_authorized_projects` so it uses a Redis lease instead of relying on serializable transactions. See the commit message(s) for more details.
See merge request !7733
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/user.rb | 36 |
1 files changed, 15 insertions, 21 deletions
diff --git a/app/models/user.rb b/app/models/user.rb index 62502efc7b4..b54ce14f0bf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -445,27 +445,21 @@ class User < ActiveRecord::Base end def refresh_authorized_projects - loop do - begin - Gitlab::Database.serialized_transaction do - project_authorizations.delete_all - - # project_authorizations_union can return multiple records for the same project/user with - # different access_level so we take row with the maximum access_level - project_authorizations.connection.execute <<-SQL - INSERT INTO project_authorizations (user_id, project_id, access_level) - SELECT user_id, project_id, MAX(access_level) AS access_level - FROM (#{project_authorizations_union.to_sql}) sub - GROUP BY user_id, project_id - SQL - - update_column(:authorized_projects_populated, true) unless authorized_projects_populated - end - - break - # In the event of a concurrent modification Rails raises StatementInvalid. - # In this case we want to keep retrying until the transaction succeeds - rescue ActiveRecord::StatementInvalid + transaction do + project_authorizations.delete_all + + # project_authorizations_union can return multiple records for the same + # project/user with different access_level so we take row with the maximum + # access_level + project_authorizations.connection.execute <<-SQL + INSERT INTO project_authorizations (user_id, project_id, access_level) + SELECT user_id, project_id, MAX(access_level) AS access_level + FROM (#{project_authorizations_union.to_sql}) sub + GROUP BY user_id, project_id + SQL + + unless authorized_projects_populated + update_column(:authorized_projects_populated, true) end end end |