Merge branch '18663-avoid-extra-yaml-serializations' into 'master'
Use update_columns to by_pass all the dirty code on active_record See merge request !4985
This commit is contained in:
commit
ad09fcb5b9
2 changed files with 38 additions and 10 deletions
|
@ -22,6 +22,7 @@ v 8.10.0 (unreleased)
|
|||
- Add basic system information like memory and disk usage to the admin panel
|
||||
|
||||
v 8.9.3 (unreleased)
|
||||
- MergeRequestDiff reload content use update_columns to avoid multiple YAML de/serializations
|
||||
- Decreased min width of screen to 1280px for pinned sidebar
|
||||
- Fix encrypted data backwards compatibility after upgrading attr_encrypted gem
|
||||
- Update mobile button icons to be more inline with typical UI paradigms
|
||||
|
|
|
@ -108,44 +108,46 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
# Reload all commits related to current merge request from repo
|
||||
# and save it as array of hashes in st_commits db field
|
||||
def reload_commits
|
||||
new_attributes = {}
|
||||
|
||||
commit_objects = unmerged_commits
|
||||
|
||||
if commit_objects.present?
|
||||
self.st_commits = dump_commits(commit_objects)
|
||||
new_attributes[:st_commits] = dump_commits(commit_objects)
|
||||
end
|
||||
|
||||
save
|
||||
update_columns_serialized(new_attributes)
|
||||
end
|
||||
|
||||
# Reload diffs between branches related to current merge request from repo
|
||||
# and save it as array of hashes in st_diffs db field
|
||||
def reload_diffs
|
||||
new_attributes = {}
|
||||
new_diffs = []
|
||||
|
||||
if commits.size.zero?
|
||||
self.state = :empty
|
||||
new_attributes[:state] = :empty
|
||||
else
|
||||
diff_collection = unmerged_diffs
|
||||
|
||||
if diff_collection.overflow?
|
||||
# Set our state to 'overflow' to make the #empty? and #collected?
|
||||
# methods (generated by StateMachine) return false.
|
||||
self.state = :overflow
|
||||
new_attributes[:state] = :overflow
|
||||
end
|
||||
|
||||
self.real_size = diff_collection.real_size
|
||||
new_attributes[:real_size] = diff_collection.real_size
|
||||
|
||||
if diff_collection.any?
|
||||
new_diffs = dump_diffs(diff_collection)
|
||||
self.state = :collected
|
||||
new_attributes[:state] = :collected
|
||||
end
|
||||
end
|
||||
|
||||
self.st_diffs = new_diffs
|
||||
new_attributes[:st_diffs] = new_diffs
|
||||
new_attributes[:base_commit_sha] = self.repository.merge_base(self.head, self.base)
|
||||
|
||||
self.base_commit_sha = self.repository.merge_base(self.head, self.base)
|
||||
|
||||
self.save
|
||||
update_columns_serialized(new_attributes)
|
||||
end
|
||||
|
||||
# Collect array of Git::Diff objects
|
||||
|
@ -190,4 +192,29 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
#
|
||||
# #save or #update_attributes providing changes on serialized attributes do a lot of
|
||||
# serialization and deserialization calls resulting in bad performance.
|
||||
# Using #update_columns solves the problem with just one YAML.dump per serialized attribute that we provide.
|
||||
# As a tradeoff we need to reload the current instance to properly manage time objects on those serialized
|
||||
# attributes. So to keep the same behaviour as the attribute assignment we reload the instance.
|
||||
# The difference is in the usage of
|
||||
# #write_attribute= (#update_attributes) and #raw_write_attribute= (#update_columns)
|
||||
#
|
||||
# Ex:
|
||||
#
|
||||
# new_attributes[:st_commits].first.slice(:committed_date)
|
||||
# => {:committed_date=>2014-02-27 11:01:38 +0200}
|
||||
# YAML.load(YAML.dump(new_attributes[:st_commits].first.slice(:committed_date)))
|
||||
# => {:committed_date=>2014-02-27 10:01:38 +0100}
|
||||
#
|
||||
def update_columns_serialized(new_attributes)
|
||||
return unless new_attributes.any?
|
||||
|
||||
update_columns(new_attributes.merge(updated_at: current_time_from_proper_timezone))
|
||||
reload
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue