Commit 4535d520 authored by Z.J. van de Weg's avatar Z.J. van de Weg

Use etag caching for environments JSON

For the index view, the environments can now be requested every 15
seconds. Any transition state of a projects environments will trigger a
cache invalidation action.

Fixes gitlab-org/gitlab-ce#31701
parent 20987f4f
......@@ -15,6 +15,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController
respond_to do |format|
format.html
format.json do
Gitlab::PollingInterval.set_header(response, interval: 15_000)
render json: {
environments: EnvironmentSerializer
.new(project: @project, current_user: @current_user)
......
......@@ -57,6 +57,10 @@ class Environment < ActiveRecord::Base
state :available
state :stopped
after_transition do |environment, _|
environment.expire_etag_cache
end
end
def predefined_variables
......@@ -205,4 +209,12 @@ class Environment < ActiveRecord::Base
def random_suffix
(0..5).map { SUFFIX_CHARS.sample }.join
end
def expire_etag_cache
Gitlab::EtagCaching::Store.new.tap do |store|
store.touch(
Gitlab::Routing.url_helpers.namespace_project_environments_path(project)
)
end
end
end
......@@ -9,7 +9,8 @@ module Gitlab
# - Ending in `noteable/issue/<id>/notes` for the `issue_notes` route
# - Ending in `issues/id`/rendered_title` for the `issue_title` route
USED_IN_ROUTES = %w[noteable issue notes issues rendered_title
commit pipelines merge_requests new].freeze
commit pipelines merge_requests new
environments].freeze
RESERVED_WORDS = DynamicPathValidator::WILDCARD_ROUTES - USED_IN_ROUTES
RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS)
ROUTES = [
......@@ -40,6 +41,10 @@ module Gitlab
Gitlab::EtagCaching::Router::Route.new(
%r(^(?!.*(#{RESERVED_WORDS})).*/pipelines/\d+\.json\z),
'project_pipeline'
),
Gitlab::EtagCaching::Router::Route.new(
%r(^(?!.*(#{RESERVED_WORDS})).*/environments\.json\z),
'environments'
)
].freeze
......
......@@ -76,6 +76,26 @@ describe Projects::EnvironmentsController do
expect(json_response['stopped_count']).to eq 1
end
end
context "when using etag caching" do
before do
RequestStore.begin!
end
after do
RequestStore.end!
RequestStore.clear!
end
it "limits the queries being executed" do
control_count = ActiveRecord::QueryRecorder.new { get :index, environment_params }.count
expect do
get :index, environment_params
get :index, environment_params
end.not_to exceed_query_limit(control_count)
end
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