summaryrefslogtreecommitdiff
path: root/app/models/ci/pipeline_status.rb
diff options
context:
space:
mode:
authorDimitrie Hoekstra <dimitrie@gitlab.com>2017-03-17 17:04:51 +0000
committerDimitrie Hoekstra <dimitrie@gitlab.com>2017-03-17 17:04:51 +0000
commitb6bab6ce47813c67ea1e2c7d4fde7d9e320da99c (patch)
tree6c1b7db2aeebc5756c73842cffef22df655cc820 /app/models/ci/pipeline_status.rb
parent116efdaf128ddcccc30fb82615cd964b35cacc53 (diff)
parentbb1620aaf712c22c61fda098260f481ad79a05e2 (diff)
downloadgitlab-ce-b6bab6ce47813c67ea1e2c7d4fde7d9e320da99c.tar.gz
Merge branch 'master' into 'focus-mode-board'focus-mode-board
# Conflicts: # app/views/shared/issuable/_filter.html.haml
Diffstat (limited to 'app/models/ci/pipeline_status.rb')
-rw-r--r--app/models/ci/pipeline_status.rb86
1 files changed, 86 insertions, 0 deletions
diff --git a/app/models/ci/pipeline_status.rb b/app/models/ci/pipeline_status.rb
new file mode 100644
index 00000000000..048047d0e34
--- /dev/null
+++ b/app/models/ci/pipeline_status.rb
@@ -0,0 +1,86 @@
+# This class is not backed by a table in the main database.
+# It loads the latest Pipeline for the HEAD of a repository, and caches that
+# in Redis.
+module Ci
+ class PipelineStatus
+ attr_accessor :sha, :status, :project, :loaded
+
+ delegate :commit, to: :project
+
+ def self.load_for_project(project)
+ new(project).tap do |status|
+ status.load_status
+ end
+ end
+
+ def initialize(project, sha: nil, status: nil)
+ @project = project
+ @sha = sha
+ @status = status
+ end
+
+ def has_status?
+ loaded? && sha.present? && status.present?
+ end
+
+ def load_status
+ return if loaded?
+
+ if has_cache?
+ load_from_cache
+ else
+ load_from_commit
+ store_in_cache
+ end
+
+ self.loaded = true
+ end
+
+ def load_from_commit
+ return unless commit
+
+ self.sha = commit.sha
+ self.status = commit.status
+ end
+
+ # We only cache the status for the HEAD commit of a project
+ # This status is rendered in project lists
+ def store_in_cache_if_needed
+ return unless sha
+ return delete_from_cache unless commit
+ store_in_cache if commit.sha == self.sha
+ end
+
+ def load_from_cache
+ Gitlab::Redis.with do |redis|
+ self.sha, self.status = redis.hmget(cache_key, :sha, :status)
+ end
+ end
+
+ def store_in_cache
+ Gitlab::Redis.with do |redis|
+ redis.mapped_hmset(cache_key, { sha: sha, status: status })
+ end
+ end
+
+ def delete_from_cache
+ Gitlab::Redis.with do |redis|
+ redis.del(cache_key)
+ end
+ end
+
+ def has_cache?
+ Gitlab::Redis.with do |redis|
+ redis.exists(cache_key)
+ end
+ end
+
+ def loaded?
+ self.loaded
+ end
+
+ def cache_key
+ "projects/#{project.id}/build_status"
+ end
+ end
+end