104 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # 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
 | |
|         attr_accessor :sha, :status, :ref, :project, :loaded
 | |
| 
 | |
|         delegate :commit, to: :project
 | |
| 
 | |
|         def self.load_for_project(project)
 | |
|           new(project).tap do |status|
 | |
|             status.load_status
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         def self.update_for_pipeline(pipeline)
 | |
|           new(pipeline.project,
 | |
|               sha: pipeline.sha,
 | |
|               status: pipeline.status,
 | |
|               ref: pipeline.ref).store_in_cache_if_needed
 | |
|         end
 | |
| 
 | |
|         def initialize(project, sha: nil, status: nil, ref: nil)
 | |
|           @project = project
 | |
|           @sha = sha
 | |
|           @ref = ref
 | |
|           @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_project
 | |
|             store_in_cache
 | |
|           end
 | |
| 
 | |
|           self.loaded = true
 | |
|         end
 | |
| 
 | |
|         def load_from_project
 | |
|           return unless commit
 | |
| 
 | |
|           self.sha = commit.sha
 | |
|           self.status = commit.status
 | |
|           self.ref = project.default_branch
 | |
|         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
 | |
|           Gitlab::Redis.with do |redis|
 | |
|             self.sha, self.status, self.ref = redis.hmget(cache_key, :sha, :status, :ref)
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         def store_in_cache
 | |
|           Gitlab::Redis.with do |redis|
 | |
|             redis.mapped_hmset(cache_key, { sha: sha, status: status, ref: ref })
 | |
|           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
 | |
|   end
 | |
| end
 |