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
This commit is contained in:
parent
50a0044228
commit
ebede2b3ff
6 changed files with 43 additions and 3 deletions
|
@ -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
|
||||
|
@ -196,6 +200,13 @@ class Environment < ActiveRecord::Base
|
|||
[external_url, public_path].join('/')
|
||||
end
|
||||
|
||||
def expire_etag_cache
|
||||
Gitlab::EtagCaching::Store.new.tap do |store|
|
||||
store.touch(Gitlab::Routing.url_helpers
|
||||
.namespace_project_environments_path(project.namespace, project))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Slugifying a name may remove the uniqueness guarantee afforded by it being
|
||||
|
|
4
changelogs/unreleased/zj-realtime-env-list.yml
Normal file
4
changelogs/unreleased/zj-realtime-env-list.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Make environment table realtime
|
||||
merge_request: 11333
|
||||
author:
|
|
@ -7,9 +7,10 @@ module Gitlab
|
|||
# - Don't contain a reserved word (expect for the words used in the
|
||||
# regex itself)
|
||||
# - Ending in `noteable/issue/<id>/notes` for the `issue_notes` route
|
||||
# - Ending in `issues/id`/realtime_changes` for the `issue_title` route
|
||||
# - Ending in `issues/id`/rendered_title` for the `issue_title` route
|
||||
USED_IN_ROUTES = %w[noteable issue notes issues realtime_changes
|
||||
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_REGEX})).*/environments\.json\z),
|
||||
'environments'
|
||||
)
|
||||
].freeze
|
||||
|
||||
|
|
|
@ -77,6 +77,16 @@ describe Gitlab::EtagCaching::Router do
|
|||
expect(result).to be_blank
|
||||
end
|
||||
|
||||
it 'matches the environments path' do
|
||||
env = build_env(
|
||||
'/my-group/my-project/environments.json'
|
||||
)
|
||||
|
||||
result = described_class.match(env)
|
||||
|
||||
expect(result).to be_blank
|
||||
end
|
||||
|
||||
def build_env(path)
|
||||
{ 'PATH_INFO' => path }
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Environment, models: true do
|
||||
let(:project) { create(:empty_project) }
|
||||
set(:project) { create(:empty_project) }
|
||||
subject(:environment) { create(:environment, project: project) }
|
||||
|
||||
it { is_expected.to belong_to(:project) }
|
||||
|
@ -34,6 +34,14 @@ describe Environment, models: true do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'state machine' do
|
||||
it 'invalidates the cache after a change' do
|
||||
expect(environment).to receive(:expire_etag_cache)
|
||||
|
||||
environment.stop
|
||||
end
|
||||
end
|
||||
|
||||
describe '#nullify_external_url' do
|
||||
it 'replaces a blank url with nil' do
|
||||
env = build(:environment, external_url: "")
|
||||
|
|
Loading…
Reference in a new issue