Class: Gitlab::Cache::Ci::ProjectPipelineStatus

Inherits:
Object
  • Object
show all
Includes:
Utils::StrongMemoize
Defined in:
lib/gitlab/cache/ci/project_pipeline_status.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils::StrongMemoize

#clear_memoization, #strong_memoize, #strong_memoized?

Constructor Details

#initialize(project, pipeline_info: {}, loaded_from_cache: nil) ⇒ ProjectPipelineStatus

Returns a new instance of ProjectPipelineStatus.


38
39
40
41
42
43
44
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 38

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

Instance Attribute Details

#loadedObject

Returns the value of attribute loaded


12
13
14
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 12

def loaded
  @loaded
end

#projectObject

Returns the value of attribute project


12
13
14
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 12

def project
  @project
end

#refObject

Returns the value of attribute ref


12
13
14
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 12

def ref
  @ref
end

#shaObject

Returns the value of attribute sha


12
13
14
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 12

def sha
  @sha
end

#statusObject

Returns the value of attribute status


12
13
14
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 12

def status
  @status
end

Class Method Details

.load_for_project(project) ⇒ Object


14
15
16
17
18
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 14

def self.load_for_project(project)
  new(project).tap do |status|
    status.load_status
  end
end

.load_in_batch_for_projects(projects) ⇒ Object


20
21
22
23
24
25
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 20

def self.load_in_batch_for_projects(projects)
  projects.each do |project|
    project.pipeline_status = new(project)
    project.pipeline_status.load_status
  end
end

.update_for_pipeline(pipeline) ⇒ Object


27
28
29
30
31
32
33
34
35
36
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 27

def self.update_for_pipeline(pipeline)
  pipeline_info = {
    sha: pipeline.sha,
    status: pipeline.status,
    ref: pipeline.ref
  }

  new(pipeline.project, pipeline_info: pipeline_info)
    .store_in_cache_if_needed
end

Instance Method Details

#cache_keyObject


119
120
121
122
123
124
125
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 119

def cache_key
  if Gitlab::Ci::Features.pipeline_status_omit_commit_sha_in_cache_key?(project)
    "#{Gitlab::Redis::Cache::CACHE_NAMESPACE}:project:#{project.id}:pipeline_status"
  else
    "#{Gitlab::Redis::Cache::CACHE_NAMESPACE}:project:#{project.id}:pipeline_status:#{commit&.sha}"
  end
end

#commitObject


127
128
129
130
131
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 127

def commit
  strong_memoize(:commit) do
    project.commit
  end
end

#delete_from_cacheObject


101
102
103
104
105
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 101

def delete_from_cache
  Gitlab::Redis::Cache.with do |redis|
    redis.del(cache_key)
  end
end

#has_cache?Boolean

Returns:

  • (Boolean)

107
108
109
110
111
112
113
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 107

def has_cache?
  return self.loaded unless self.loaded.nil?

  Gitlab::Redis::Cache.with do |redis|
    redis.exists(cache_key)
  end
end

#has_status?Boolean

Returns:

  • (Boolean)

46
47
48
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 46

def has_status?
  loaded? && sha.present? && status.present?
end

#load_from_cacheObject


87
88
89
90
91
92
93
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 87

def load_from_cache
  Gitlab::Redis::Cache.with do |redis|
    self.sha, self.status, self.ref = redis.hmget(cache_key, :sha, :status, :ref)

    self.status = nil if self.status.empty?
  end
end

#load_from_projectObject


69
70
71
72
73
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 69

def load_from_project
  return unless commit

  self.sha, self.status, self.ref = commit.sha, commit.status, project.default_branch
end

#load_statusObject


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 50

def load_status
  return if loaded?

  return unless Gitlab::Ci::Features.pipeline_status_omit_commit_sha_in_cache_key?(project) || commit

  if has_cache?
    load_from_cache
  else
    load_from_project
    store_in_cache
  end

  self.loaded = true
rescue GRPC::Unavailable, GRPC::DeadlineExceeded => e
  # Handle Gitaly connection issues gracefully
  Gitlab::ErrorTracking
    .track_exception(e, project_id: project.id)
end

#loaded?Boolean

Returns:

  • (Boolean)

115
116
117
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 115

def loaded?
  self.loaded
end

#store_in_cacheObject


95
96
97
98
99
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 95

def store_in_cache
  Gitlab::Redis::Cache.with do |redis|
    redis.mapped_hmset(cache_key, { sha: sha, status: status, ref: ref })
  end
end

#store_in_cache_if_neededObject

We only cache the status for the HEAD commit of a project This status is rendered in project lists


77
78
79
80
81
82
83
84
85
# File 'lib/gitlab/cache/ci/project_pipeline_status.rb', line 77

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