diff options
author | Z.J. van de Weg <git@zjvandeweg.nl> | 2017-05-12 15:19:27 +0200 |
---|---|---|
committer | Z.J. van de Weg <git@zjvandeweg.nl> | 2017-05-12 15:43:57 +0200 |
commit | 4535d520327206e49e438abe8759ccb134955e54 (patch) | |
tree | dfd914784a2f10b034ad6c95d9d94f4bc802eff6 | |
parent | 20987f4fd2d6a5ab27e61a4afc038999937adade (diff) | |
download | gitlab-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.rb | 2 | ||||
-rw-r--r-- | app/models/environment.rb | 12 | ||||
-rw-r--r-- | lib/gitlab/etag_caching/router.rb | 7 | ||||
-rw-r--r-- | spec/controllers/projects/environments_controller_spec.rb | 20 |
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 |