diff options
author | Oswaldo Ferreira <oswaldo@gitlab.com> | 2018-06-06 22:01:37 -0300 |
---|---|---|
committer | Oswaldo Ferreira <oswaldo@gitlab.com> | 2018-06-06 22:01:37 -0300 |
commit | 8d82db5b739c510919bfb3f89cb7b142156ba6c5 (patch) | |
tree | c1b5a047bc6c3873ee4729fa28996194c579738d | |
parent | c92902791f2de83d62f446076c4b8ed69ab7a57b (diff) | |
download | gitlab-ce-8d82db5b739c510919bfb3f89cb7b142156ba6c5.tar.gz |
Create CachedBlob class
-rw-r--r-- | app/models/blobs_service.rb | 58 | ||||
-rw-r--r-- | app/models/cached_blob.rb | 11 | ||||
-rw-r--r-- | lib/gitlab/diff/file.rb | 12 |
3 files changed, 43 insertions, 38 deletions
diff --git a/app/models/blobs_service.rb b/app/models/blobs_service.rb index 5469c3a9a3e..5e4adc3a95d 100644 --- a/app/models/blobs_service.rb +++ b/app/models/blobs_service.rb @@ -1,57 +1,55 @@ -# This is a wrapper for Blob model. +# This is a thin caching wrapper class for Blob model. # It acts as a thin layer which caches lightweight information # based on the blob content (which is not cached). class BlobsService + CACHED_METHODS = %i(id raw_size size readable_text? name raw_binary? binary? path + external_storage_error? stored_externally? total_lines).freeze + def initialize(project, content_sha, path) @project = project @content_sha = content_sha @path = path end + # We need blobs data (content) in order to highlight diffs (see + # Gitlab::Diff:Highlight), and we don't cache this (Blob#data) on Redis, + # mainly because it's a quite heavy information to cache for every blob. + # + # Therefore, in this scenario (no highlight yet) we use the uncached blob + # version. + def fetch(highlighted:) + return unless content_sha + return uncached_blob unless highlighted + + cache_exists? ? cached_blob : uncached_blob + end + + def write_cache_if_empty return unless content_sha return if cache_exists? return unless uncached_blob - blob_cache = { id: uncached_blob.id, - raw_size: uncached_blob.raw_size, - size: uncached_blob.size, - readable_text: uncached_blob.readable_text?, - name: uncached_blob.name, - binary: uncached_blob.binary?, - path: uncached_blob.path, - external_storage_error: uncached_blob.external_storage_error?, - stored_externally: uncached_blob.stored_externally?, - total_lines: uncached_blob.total_lines } - - cache.write(cache_key, blob_cache, expires_in: 1.week) + cache.write(cache_key, cacheable_blob_hash, expires_in: 1.week) end def clear_cache cache.delete(cache_key) end - # We need blobs data (content) in order to highlight diffs (see - # Gitlab::Diff:Highlight), and we don't cache this (Blob#data) on Redis, - # mainly because it's a quite heavy information to cache for every blob. - # - # Therefore, in this scenario (no highlight yet) we use the uncached blob - # version. - def blob(highlighted:) - return unless content_sha - return uncached_blob unless highlighted + private + + attr_reader :content_sha - if cache_exists? - # TODO: This can be a CachedBlob - Hashie::Mash.new(read_cache) - else - uncached_blob + def cacheable_blob_hash + CACHED_METHODS.each_with_object({}) do |_method, hash| + hash[_method] = uncached_blob.public_send(_method) end end - private - - attr_reader :content_sha + def cached_blob + CachedBlob.new(read_cache) + end def uncached_blob @uncached_blob ||= Blob.lazy(@project, @content_sha, @path)&.itself diff --git a/app/models/cached_blob.rb b/app/models/cached_blob.rb new file mode 100644 index 00000000000..fa95ecc70bd --- /dev/null +++ b/app/models/cached_blob.rb @@ -0,0 +1,11 @@ +class CachedBlob + delegate *BlobsService::CACHED_METHODS, to: :@blob_cache + + def initialize(blob_cache) + @blob_cache = Hashie::Mash.new(blob_cache) + end + + def load_all_data! + # no-op + end +end diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb index 39a64502f67..95e2df007fd 100644 --- a/lib/gitlab/diff/file.rb +++ b/lib/gitlab/diff/file.rb @@ -104,23 +104,19 @@ module Gitlab end def new_blob_service - BlobsService.new(repository.project, - new_content_sha, - file_path) + BlobsService.new(repository.project, new_content_sha, file_path) end def old_blob_service - BlobsService.new(repository.project, - old_content_sha, - file_path) + BlobsService.new(repository.project, old_content_sha, file_path) end def new_blob - new_blob_service.blob(highlighted: highlighted?) + new_blob_service.fetch(highlighted: highlighted?) end def old_blob - old_blob_service.blob(highlighted: highlighted?) + old_blob_service.fetch(highlighted: highlighted?) end def content_sha |