Commit ebede2b3 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 50a00442
...@@ -15,6 +15,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController ...@@ -15,6 +15,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController
respond_to do |format| respond_to do |format|
format.html format.html
format.json do format.json do
Gitlab::PollingInterval.set_header(response, interval: 15_000)
render json: { render json: {
environments: EnvironmentSerializer environments: EnvironmentSerializer
.new(project: @project, current_user: @current_user) .new(project: @project, current_user: @current_user)
......
...@@ -57,6 +57,10 @@ class Environment < ActiveRecord::Base ...@@ -57,6 +57,10 @@ class Environment < ActiveRecord::Base
state :available state :available
state :stopped state :stopped
after_transition do |environment|
environment.expire_etag_cache
end
end end
def predefined_variables def predefined_variables
...@@ -196,6 +200,13 @@ class Environment < ActiveRecord::Base ...@@ -196,6 +200,13 @@ class Environment < ActiveRecord::Base
[external_url, public_path].join('/') [external_url, public_path].join('/')
end 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 private
# Slugifying a name may remove the uniqueness guarantee afforded by it being # Slugifying a name may remove the uniqueness guarantee afforded by it being
......
---
title: Make environment table realtime
merge_request: 11333
author:
...@@ -7,9 +7,10 @@ module Gitlab ...@@ -7,9 +7,10 @@ module Gitlab
# - Don't contain a reserved word (expect for the words used in the # - Don't contain a reserved word (expect for the words used in the
# regex itself) # regex itself)
# - Ending in `noteable/issue/<id>/notes` for the `issue_notes` route # - 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 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 = DynamicPathValidator::WILDCARD_ROUTES - USED_IN_ROUTES
RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS) RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS)
ROUTES = [ ROUTES = [
...@@ -40,6 +41,10 @@ module Gitlab ...@@ -40,6 +41,10 @@ module Gitlab
Gitlab::EtagCaching::Router::Route.new( Gitlab::EtagCaching::Router::Route.new(
%r(^(?!.*(#{RESERVED_WORDS})).*/pipelines/\d+\.json\z), %r(^(?!.*(#{RESERVED_WORDS})).*/pipelines/\d+\.json\z),
'project_pipeline' 'project_pipeline'
),
Gitlab::EtagCaching::Router::Route.new(
%r(^(?!.*(#{RESERVED_WORDS_REGEX})).*/environments\.json\z),
'environments'
) )
].freeze ].freeze
......
...@@ -77,6 +77,16 @@ describe Gitlab::EtagCaching::Router do ...@@ -77,6 +77,16 @@ describe Gitlab::EtagCaching::Router do
expect(result).to be_blank expect(result).to be_blank
end 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) def build_env(path)
{ 'PATH_INFO' => path } { 'PATH_INFO' => path }
end end
......
require 'spec_helper' require 'spec_helper'
describe Environment, models: true do describe Environment, models: true do
let(:project) { create(:empty_project) } set(:project) { create(:empty_project) }
subject(:environment) { create(:environment, project: project) } subject(:environment) { create(:environment, project: project) }
it { is_expected.to belong_to(:project) } it { is_expected.to belong_to(:project) }
...@@ -34,6 +34,14 @@ describe Environment, models: true do ...@@ -34,6 +34,14 @@ describe Environment, models: true do
end end
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 describe '#nullify_external_url' do
it 'replaces a blank url with nil' do it 'replaces a blank url with nil' do
env = build(:environment, external_url: "") env = build(:environment, external_url: "")
......
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