Try not to hold env and release the controller

after the request. This way, we could release the
project referred from the controller, which potentially
referred a repository which potentially allocated a lot of
memories.

Before this change, we could hold the last request data
and cannot release the memory. After this change, the
largest request data should be able to be collected from GC.

This might not impact the instances having heavy load,
as the last request should be changing all the time,
and GC won't kick in for each request anyway.

However it could still potentially allow us to free more
memories for each GC runs, because now we could free one
more request anyway.
This commit is contained in:
Lin Jen-Shin 2018-02-01 18:48:32 +08:00
parent 0b9825ca46
commit d4d564c8e7
4 changed files with 31 additions and 1 deletions

View File

@ -23,5 +23,6 @@ warmup do |app|
end
map ENV['RAILS_RELATIVE_URL_ROOT'] || "/" do
use Gitlab::ReleaseController
run Gitlab::Application
end

View File

@ -28,7 +28,7 @@ module Gitlab
end
end
@app.call(env)
@app.call(env).tap { @env = nil }
end
private

View File

@ -0,0 +1,9 @@
module Gitlab
module Middleware
ReleaseController = Struct.new(:app) do
def call(env)
app.call(env).tap { env.delete('action_controller.instance') }
end
end
end
end

View File

@ -0,0 +1,20 @@
require 'spec_helper'
describe Gitlab::Middleware::ReleaseController do
let(:inner_app) { double(:app) }
let(:app) { described_class.new(inner_app) }
let(:env) { { 'action_controller.instance' => 'something' } }
before do
expect(inner_app).to receive(:call).with(env).and_return('yay')
end
describe '#call' do
it 'calls the app and delete the controller' do
result = app.call(env)
expect(result).to eq('yay')
expect(env).to be_empty
end
end
end