summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOswaldo Ferreira <oswaldo@gitlab.com>2018-06-06 22:01:37 -0300
committerOswaldo Ferreira <oswaldo@gitlab.com>2018-06-06 22:01:37 -0300
commit8d82db5b739c510919bfb3f89cb7b142156ba6c5 (patch)
treec1b5a047bc6c3873ee4729fa28996194c579738d
parentc92902791f2de83d62f446076c4b8ed69ab7a57b (diff)
downloadgitlab-ce-8d82db5b739c510919bfb3f89cb7b142156ba6c5.tar.gz
Create CachedBlob class
-rw-r--r--app/models/blobs_service.rb58
-rw-r--r--app/models/cached_blob.rb11
-rw-r--r--lib/gitlab/diff/file.rb12
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