summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZ.J. van de Weg <git@zjvandeweg.nl>2017-05-12 15:19:27 +0200
committerZ.J. van de Weg <git@zjvandeweg.nl>2017-05-12 15:43:57 +0200
commit4535d520327206e49e438abe8759ccb134955e54 (patch)
treedfd914784a2f10b034ad6c95d9d94f4bc802eff6
parent20987f4fd2d6a5ab27e61a4afc038999937adade (diff)
downloadgitlab-ce-4535d520327206e49e438abe8759ccb134955e54.tar.gz
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
-rw-r--r--app/controllers/projects/environments_controller.rb2
-rw-r--r--app/models/environment.rb12
-rw-r--r--lib/gitlab/etag_caching/router.rb7
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb20
4 files changed, 40 insertions, 1 deletions
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index fd57afbd05f..537c74d5231 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -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)
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 61efc1b2d17..959129da67f 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -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
diff --git a/lib/gitlab/etag_caching/router.rb b/lib/gitlab/etag_caching/router.rb
index 31a5b9d108b..174fee5ee24 100644
--- a/lib/gitlab/etag_caching/router.rb
+++ b/lib/gitlab/etag_caching/router.rb
@@ -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
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index c0f8c36a018..19cea1adbf6 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -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