Commit 15c8d29b authored by Sarah Yasonik's avatar Sarah Yasonik Committed by Douglas Barbosa Alexandre

Refactor for cleaner caching in dashboards

Opts to cache a full list of cached dashboards
to better manage removing items from the cache.
This also allows dashboards to be stored in the
cache that don't necessarily correspond to a
single dashboard yml.
parent ee458c91
......@@ -164,7 +164,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
if Feature.enabled?(:environment_metrics_show_multiple_dashboards, project)
result = dashboard_finder.find(project, current_user, environment, params[:dashboard])
result[:all_dashboards] = project.repository.metrics_dashboard_paths
result[:all_dashboards] = dashboard_finder.find_all_paths(project)
else
result = dashboard_finder.find(project, current_user, environment)
end
......
......@@ -7,18 +7,19 @@ module Gitlab
module Dashboard
class BaseService < ::BaseService
PROCESSING_ERROR = Gitlab::Metrics::Dashboard::Stages::BaseStage::DashboardProcessingError
NOT_FOUND_ERROR = Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError
def get_dashboard
return error("#{dashboard_path} could not be found.", :not_found) unless path_available?
success(dashboard: process_dashboard)
rescue NOT_FOUND_ERROR
error("#{dashboard_path} could not be found.", :not_found)
rescue PROCESSING_ERROR => e
error(e.message, :unprocessable_entity)
end
# Summary of all known dashboards for the service.
# @return [Array<Hash>] ex) [{ path: String, default: Boolean }]
def all_dashboard_paths(_project)
def self.all_dashboard_paths(_project)
raise NotImplementedError
end
......@@ -38,7 +39,7 @@ module Gitlab
# Returns an un-processed dashboard from the cache.
def raw_dashboard
Rails.cache.fetch(cache_key) { get_raw_dashboard }
Gitlab::Metrics::Dashboard::Cache.fetch(cache_key) { get_raw_dashboard }
end
# @return [Hash] an unmodified dashboard
......@@ -56,17 +57,6 @@ module Gitlab
def insert_project_metrics?
false
end
# Checks if dashboard path exists or should be rejected
# as a result of file-changes to the project repository.
# @return [Boolean]
def path_available?
available_paths = Gitlab::Metrics::Dashboard::Finder.find_all_paths(project)
available_paths.any? do |path_params|
path_params[:path] == dashboard_path
end
end
end
end
end
......
# frozen_string_literal: true
require 'set'
module Gitlab
module Metrics
module Dashboard
class Cache
CACHE_KEYS = 'all_cached_metric_dashboards'
class << self
# Stores a dashboard in the cache, documenting the key
# so the cached can be cleared in bulk at another time.
def fetch(key)
register_key(key)
Rails.cache.fetch(key) { yield }
end
# Resets all dashboard caches, such that all
# dashboard content will be loaded from source on
# subsequent dashboard calls.
def delete_all!
all_keys.each { |key| Rails.cache.delete(key) }
Rails.cache.delete(CACHE_KEYS)
end
private
def register_key(key)
new_keys = all_keys.add(key).to_a.join('|')
Rails.cache.write(CACHE_KEYS, new_keys)
end
def all_keys
Set.new(Rails.cache.read(CACHE_KEYS)&.split('|'))
end
end
end
end
end
end
......@@ -27,6 +27,8 @@ module Gitlab
# Summary of all known dashboards. Used to populate repo cache.
# Prefer #find_all_paths.
def find_all_paths_from_source(project)
Gitlab::Metrics::Dashboard::Cache.delete_all!
system_service.all_dashboard_paths(project)
.+ project_service.all_dashboard_paths(project)
end
......
......@@ -13,20 +13,12 @@ module Gitlab
def all_dashboard_paths(project)
file_finder(project)
.list_files_for(DASHBOARD_ROOT)
.map do |filepath|
Rails.cache.delete(cache_key(project.id, filepath))
{ path: filepath, default: false }
end
.map { |filepath| { path: filepath, default: false } }
end
def file_finder(project)
Gitlab::Template::Finders::RepoTemplateFinder.new(project, DASHBOARD_ROOT, '.yml')
end
def cache_key(id, dashboard_path)
"project_#{id}_metrics_dashboard_#{dashboard_path}"
end
end
private
......@@ -39,7 +31,7 @@ module Gitlab
end
def cache_key
self.class.cache_key(project.id, dashboard_path)
"project_#{project.id}_metrics_dashboard_#{dashboard_path}"
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment