debian-mirror-gitlab/lib/gitlab/cache/ci/project_pipeline_status.rb

129 lines
3.4 KiB
Ruby
Raw Normal View History

2018-12-13 13:39:08 +05:30
# frozen_string_literal: true
2017-08-17 22:00:37 +05:30
# 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 Gitlab
module Cache
module Ci
class ProjectPipelineStatus
2019-02-15 15:39:39 +05:30
include Gitlab::Utils::StrongMemoize
2017-08-17 22:00:37 +05:30
2019-02-15 15:39:39 +05:30
attr_accessor :sha, :status, :ref, :project, :loaded
2019-01-03 12:48:30 +05:30
2017-08-17 22:00:37 +05:30
def self.load_for_project(project)
new(project).tap do |status|
status.load_status
end
end
def self.load_in_batch_for_projects(projects)
2019-02-15 15:39:39 +05:30
projects.each do |project|
project.pipeline_status = new(project)
2017-08-17 22:00:37 +05:30
project.pipeline_status.load_status
end
end
def self.update_for_pipeline(pipeline)
pipeline_info = {
sha: pipeline.sha,
status: pipeline.status,
ref: pipeline.ref
}
2017-09-10 17:25:29 +05:30
new(pipeline.project, pipeline_info: pipeline_info)
.store_in_cache_if_needed
2017-08-17 22:00:37 +05:30
end
def initialize(project, pipeline_info: {}, loaded_from_cache: nil)
@project = project
@sha = pipeline_info[:sha]
@ref = pipeline_info[:ref]
@status = pipeline_info[:status]
@loaded = loaded_from_cache
end
def has_status?
loaded? && sha.present? && status.present?
end
def load_status
return if loaded?
2019-02-15 15:39:39 +05:30
return unless commit
2017-08-17 22:00:37 +05:30
if has_cache?
load_from_cache
else
load_from_project
store_in_cache
end
self.loaded = true
2020-03-09 13:42:32 +05:30
rescue GRPC::Unavailable, GRPC::DeadlineExceeded => e
# Handle Gitaly connection issues gracefully
Gitlab::ErrorTracking
.track_exception(e, project_id: project.id)
2017-08-17 22:00:37 +05:30
end
def load_from_project
2018-12-13 13:39:08 +05:30
self.sha, self.status, self.ref = commit.sha, commit.status, project.default_branch
2017-08-17 22:00:37 +05:30
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 delete_from_cache unless commit
return unless sha
return unless ref
if commit.sha == sha && project.default_branch == ref
store_in_cache
end
end
def load_from_cache
2017-09-10 17:25:29 +05:30
Gitlab::Redis::Cache.with do |redis|
2017-08-17 22:00:37 +05:30
self.sha, self.status, self.ref = redis.hmget(cache_key, :sha, :status, :ref)
2018-12-13 13:39:08 +05:30
self.status = nil if self.status.empty?
2017-08-17 22:00:37 +05:30
end
end
def store_in_cache
2017-09-10 17:25:29 +05:30
Gitlab::Redis::Cache.with do |redis|
2017-08-17 22:00:37 +05:30
redis.mapped_hmset(cache_key, { sha: sha, status: status, ref: ref })
end
end
def delete_from_cache
2017-09-10 17:25:29 +05:30
Gitlab::Redis::Cache.with do |redis|
2017-08-17 22:00:37 +05:30
redis.del(cache_key)
end
end
def has_cache?
return self.loaded unless self.loaded.nil?
2017-09-10 17:25:29 +05:30
Gitlab::Redis::Cache.with do |redis|
2017-08-17 22:00:37 +05:30
redis.exists(cache_key)
end
end
def loaded?
self.loaded
end
def cache_key
2019-02-15 15:39:39 +05:30
"#{Gitlab::Redis::Cache::CACHE_NAMESPACE}:project:#{project.id}:pipeline_status:#{commit&.sha}"
end
def commit
strong_memoize(:commit) do
project.commit
end
2017-08-17 22:00:37 +05:30
end
end
end
end
end