Commit 5371da34 authored by Yorick Peterse's avatar Yorick Peterse

Remove event caching code

Flushing the events cache worked by updating a recent number of rows in
the "events" table. This has the result that on PostgreSQL a lot of dead
tuples are produced on a regular basis. This in turn means that
PostgreSQL will spend considerable amounts of time vacuuming this table.
This in turn can lead to an increase of database load.

For GitLab.com we measured the impact of not using events caching and
found no measurable increase in response timings. Meanwhile not flushing
the events cache lead to the "events" table having no more dead tuples
as now rows are only inserted into this table.

As a result of this we are hereby removing events caching as it does not
appear to help and only increases database load.

For more information see the following comment:
https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6578#note_18864037
parent d7eeb6df
...@@ -4,7 +4,6 @@ class Profiles::AvatarsController < Profiles::ApplicationController ...@@ -4,7 +4,6 @@ class Profiles::AvatarsController < Profiles::ApplicationController
@user.remove_avatar! @user.remove_avatar!
@user.save @user.save
@user.reset_events_cache
redirect_to profile_path redirect_to profile_path
end end
......
...@@ -20,7 +20,6 @@ class Projects::AvatarsController < Projects::ApplicationController ...@@ -20,7 +20,6 @@ class Projects::AvatarsController < Projects::ApplicationController
@project.remove_avatar! @project.remove_avatar!
@project.save @project.save
@project.reset_events_cache
redirect_to edit_project_path(@project) redirect_to edit_project_path(@project)
end end
......
...@@ -43,12 +43,6 @@ class Event < ActiveRecord::Base ...@@ -43,12 +43,6 @@ class Event < ActiveRecord::Base
scope :for_milestone_id, ->(milestone_id) { where(target_type: "Milestone", target_id: milestone_id) } scope :for_milestone_id, ->(milestone_id) { where(target_type: "Milestone", target_id: milestone_id) }
class << self class << self
def reset_event_cache_for(target)
Event.where(target_id: target.id, target_type: target.class.to_s).
order('id DESC').limit(100).
update_all(updated_at: Time.now)
end
# Update Gitlab::ContributionsCalendar#activity_dates if this changes # Update Gitlab::ContributionsCalendar#activity_dates if this changes
def contributions def contributions
where("action = ? OR (target_type in (?) AND action in (?))", where("action = ? OR (target_type in (?) AND action in (?))",
......
...@@ -182,18 +182,6 @@ class Issue < ActiveRecord::Base ...@@ -182,18 +182,6 @@ class Issue < ActiveRecord::Base
branches_with_iid - branches_with_merge_request branches_with_iid - branches_with_merge_request
end end
# Reset issue events cache
#
# Since we do cache @event we need to reset cache in special cases:
# * when an issue is updated
# Events cache stored like events/23-20130109142513.
# The cache key includes updated_at timestamp.
# Thus it will automatically generate a new fragment
# when the event is updated because the key changes.
def reset_events_cache
Event.reset_event_cache_for(self)
end
# To allow polymorphism with MergeRequest. # To allow polymorphism with MergeRequest.
def source_project def source_project
project project
......
...@@ -601,18 +601,6 @@ class MergeRequest < ActiveRecord::Base ...@@ -601,18 +601,6 @@ class MergeRequest < ActiveRecord::Base
self.target_project.repository.branch_names.include?(self.target_branch) self.target_project.repository.branch_names.include?(self.target_branch)
end end
# Reset merge request events cache
#
# Since we do cache @event we need to reset cache in special cases:
# * when a merge request is updated
# Events cache stored like events/23-20130109142513.
# The cache key includes updated_at timestamp.
# Thus it will automatically generate a new fragment
# when the event is updated because the key changes.
def reset_events_cache
Event.reset_event_cache_for(self)
end
def merge_commit_message def merge_commit_message
message = "Merge branch '#{source_branch}' into '#{target_branch}'\n\n" message = "Merge branch '#{source_branch}' into '#{target_branch}'\n\n"
message << "#{title}\n\n" message << "#{title}\n\n"
......
...@@ -198,19 +198,6 @@ class Note < ActiveRecord::Base ...@@ -198,19 +198,6 @@ class Note < ActiveRecord::Base
super(noteable_type.to_s.classify.constantize.base_class.to_s) super(noteable_type.to_s.classify.constantize.base_class.to_s)
end end
# Reset notes events cache
#
# Since we do cache @event we need to reset cache in special cases:
# * when a note is updated
# * when a note is removed
# Events cache stored like events/23-20130109142513.
# The cache key includes updated_at timestamp.
# Thus it will automatically generate a new fragment
# when the event is updated because the key changes.
def reset_events_cache
Event.reset_event_cache_for(self)
end
def editable? def editable?
!system? !system?
end end
......
...@@ -973,7 +973,6 @@ class Project < ActiveRecord::Base ...@@ -973,7 +973,6 @@ class Project < ActiveRecord::Base
begin begin
gitlab_shell.mv_repository(repository_storage_path, "#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki") gitlab_shell.mv_repository(repository_storage_path, "#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki")
send_move_instructions(old_path_with_namespace) send_move_instructions(old_path_with_namespace)
reset_events_cache
@old_path_with_namespace = old_path_with_namespace @old_path_with_namespace = old_path_with_namespace
...@@ -1040,22 +1039,6 @@ class Project < ActiveRecord::Base ...@@ -1040,22 +1039,6 @@ class Project < ActiveRecord::Base
attrs attrs
end end
# Reset events cache related to this project
#
# Since we do cache @event we need to reset cache in special cases:
# * when project was moved
# * when project was renamed
# * when the project avatar changes
# Events cache stored like events/23-20130109142513.
# The cache key includes updated_at timestamp.
# Thus it will automatically generate a new fragment
# when the event is updated because the key changes.
def reset_events_cache
Event.where(project_id: self.id).
order('id DESC').limit(100).
update_all(updated_at: Time.now)
end
def project_member(user) def project_member(user)
project_members.find_by(user_id: user) project_members.find_by(user_id: user)
end end
......
...@@ -704,20 +704,6 @@ class User < ActiveRecord::Base ...@@ -704,20 +704,6 @@ class User < ActiveRecord::Base
project.project_member(self) project.project_member(self)
end end
# Reset project events cache related to this user
#
# Since we do cache @event we need to reset cache in special cases:
# * when the user changes their avatar
# Events cache stored like events/23-20130109142513.
# The cache key includes updated_at timestamp.
# Thus it will automatically generate a new fragment
# when the event is updated because the key changes.
def reset_events_cache
Event.where(author_id: id).
order('id DESC').limit(1000).
update_all(updated_at: Time.now)
end
def full_website_url def full_website_url
return "http://#{website_url}" if website_url !~ /\Ahttps?:\/\// return "http://#{website_url}" if website_url !~ /\Ahttps?:\/\//
......
...@@ -184,8 +184,6 @@ class IssuableBaseService < BaseService ...@@ -184,8 +184,6 @@ class IssuableBaseService < BaseService
params[:label_ids] = process_label_ids(params, existing_label_ids: issuable.label_ids) params[:label_ids] = process_label_ids(params, existing_label_ids: issuable.label_ids)
if params.present? && update_issuable(issuable, params) if params.present? && update_issuable(issuable, params)
issuable.reset_events_cache
# We do not touch as it will affect a update on updated_at field # We do not touch as it will affect a update on updated_at field
ActiveRecord::Base.no_touching do ActiveRecord::Base.no_touching do
handle_common_system_notes(issuable, old_labels: old_labels) handle_common_system_notes(issuable, old_labels: old_labels)
......
...@@ -2,7 +2,6 @@ module Notes ...@@ -2,7 +2,6 @@ module Notes
class DeleteService < BaseService class DeleteService < BaseService
def execute(note) def execute(note)
note.destroy note.destroy
note.reset_events_cache
end end
end end
end end
...@@ -5,7 +5,6 @@ module Notes ...@@ -5,7 +5,6 @@ module Notes
note.update_attributes(params.merge(updated_by: current_user)) note.update_attributes(params.merge(updated_by: current_user))
note.create_new_cross_references!(current_user) note.create_new_cross_references!(current_user)
note.reset_events_cache
if note.previous_changes.include?('note') if note.previous_changes.include?('note')
TodoService.new.update_note(note, current_user) TodoService.new.update_note(note, current_user)
......
...@@ -61,9 +61,6 @@ module Projects ...@@ -61,9 +61,6 @@ module Projects
# Move missing group labels to project # Move missing group labels to project
Labels::TransferService.new(current_user, old_group, project).execute Labels::TransferService.new(current_user, old_group, project).execute
# clear project cached events
project.reset_events_cache
# Move uploads # Move uploads
Gitlab::UploadsTransfer.new.move_project(project.path, old_namespace.path, new_namespace.path) Gitlab::UploadsTransfer.new.move_project(project.path, old_namespace.path, new_namespace.path)
......
...@@ -3,16 +3,10 @@ class AvatarUploader < CarrierWave::Uploader::Base ...@@ -3,16 +3,10 @@ class AvatarUploader < CarrierWave::Uploader::Base
storage :file storage :file
after :store, :reset_events_cache
def store_dir def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end end
def reset_events_cache(file)
model.reset_events_cache if model.is_a?(User)
end
def exists? def exists?
model.avatar.file && model.avatar.file.exists? model.avatar.file && model.avatar.file.exists?
end end
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
.event-item-timestamp .event-item-timestamp
#{time_ago_with_tooltip(event.created_at)} #{time_ago_with_tooltip(event.created_at)}
= cache [event, current_application_settings, "v2.2"] do
= author_avatar(event, size: 40) = author_avatar(event, size: 40)
- if event.created_project? - if event.created_project?
......
---
title: Remove caching of events data
merge_request: 6578
author:
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment