diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2016-10-04 18:22:58 +0300 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2016-10-04 20:41:37 +0300 |
commit | c9bcfc631a79db97203d51d7c221a7549ba65adf (patch) | |
tree | 01a8be8de90c498e916bc9f6d8c2bc7478e89226 /app/models/event.rb | |
parent | 7887a3dafb6902cc39c831e307c48faf49f80b51 (diff) |
Remove lease from Event#reset_project_activity
Per GitLab.com's performance metrics this method could take up to 5
seconds of wall time to complete, while only taking 1-2 milliseconds of
CPU time. Removing the Redis lease in favour of conditional updates
allows us to work around this.
A slight drawback is that this allows for multiple threads/processes to
try and update the same row. However, only a single thread/process will
ever win since the UPDATE query uses a WHERE condition to only update
rows that were not updated in the last hour.
Fixes gitlab-org/gitlab-ce#22473
Diffstat (limited to 'app/models/event.rb')
-rw-r--r-- | app/models/event.rb | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/app/models/event.rb b/app/models/event.rb index 55a76e26f3c..633019fe0af 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -328,13 +328,15 @@ class Event < ActiveRecord::Base def reset_project_activity return unless project - # Don't even bother obtaining a lock if the last update happened less than - # 60 minutes ago. + # Don't bother updating if we know the project was updated recently. return if recent_update? - return unless try_obtain_lease - - project.update_column(:last_activity_at, created_at) + # At this point it's possible for multiple threads/processes to try to + # update the project. Only one query should actually perform the update, + # hence we add the extra WHERE clause for last_activity_at. + Project.unscoped.where(id: project_id). + where('last_activity_at > ?', RESET_PROJECT_ACTIVITY_INTERVAL.ago). + update_all(last_activity_at: created_at) end private @@ -342,11 +344,4 @@ class Event < ActiveRecord::Base def recent_update? project.last_activity_at > RESET_PROJECT_ACTIVITY_INTERVAL.ago end - - def try_obtain_lease - Gitlab::ExclusiveLease. - new("project:update_last_activity_at:#{project.id}", - timeout: RESET_PROJECT_ACTIVITY_INTERVAL.to_i). - try_obtain - end end |