Commit a1859fbe authored by Matthias Käppler's avatar Matthias Käppler Committed by Kamil Trzciński

Add a chaos endpoint that triggers GC

This helps in providing a stable view on worker memory
during development and performance tests.
parent 24590717
......@@ -23,6 +23,15 @@ class ChaosController < ActionController::Base
do_chaos :kill, Chaos::KillWorker
end
def gc
gc_stat = Gitlab::Chaos.run_gc
render json: {
worker_id: Prometheus::PidProvider.worker_id,
gc_stat: gc_stat
}
end
private
def do_chaos(method, worker, *args)
......
......@@ -158,6 +158,7 @@ Rails.application.routes.draw do
get :db_spin
get :sleep
get :kill
post :gc
end
end
......
......@@ -160,3 +160,58 @@ GET /-/chaos/kill?async=true
curl "http://localhost:3000/-/chaos/kill" --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/kill?token=secret"
```
## Run garbage collector
This endpoint triggers a GC run on the worker handling the request and returns its worker ID
plus GC stats as JSON. This is mostly useful when running Puma in standalone mode, since
otherwise the worker handling the request will not be known upfront.
Endpoint:
```plaintext
POST /-/chaos/gc
```
Example request:
```shell
curl --request POST "http://localhost:3000/-/chaos/gc" --header 'X-Chaos-Secret: secret'
curl --request POST "http://localhost:3000/-/chaos/gc?token=secret"
```
Example response:
```json
{
"worker_id": "puma_1",
"gc_stat": {
"count": 94,
"heap_allocated_pages": 9077,
"heap_sorted_length": 9077,
"heap_allocatable_pages": 0,
"heap_available_slots": 3699720,
"heap_live_slots": 2827510,
"heap_free_slots": 872210,
"heap_final_slots": 0,
"heap_marked_slots": 2827509,
"heap_eden_pages": 9077,
"heap_tomb_pages": 0,
"total_allocated_pages": 9077,
"total_freed_pages": 0,
"total_allocated_objects": 14229357,
"total_freed_objects": 11401847,
"malloc_increase_bytes": 8192,
"malloc_increase_bytes_limit": 30949538,
"minor_gc_count": 71,
"major_gc_count": 23,
"compact_count": 0,
"remembered_wb_unprotected_objects": 41685,
"remembered_wb_unprotected_objects_limit": 83370,
"old_objects": 2617806,
"old_objects_limit": 5235612,
"oldmalloc_increase_bytes": 8192,
"oldmalloc_increase_bytes_limit": 122713697
}
}
```
......@@ -47,5 +47,13 @@ module Gitlab
def self.kill
Process.kill("KILL", Process.pid)
end
def self.run_gc
# Tenure any live objects from young-gen to old-gen
4.times { GC.start(full_mark: false) }
# Run a full mark-and-sweep collection
GC.start
GC.stat
end
end
end
......@@ -124,4 +124,23 @@ RSpec.describe ChaosController do
expect(response).to have_gitlab_http_status(:ok)
end
end
describe '#gc' do
let(:gc_stat) { GC.stat.stringify_keys }
it 'runs a full GC on the current web worker' do
expect(Prometheus::PidProvider).to receive(:worker_id).and_return('worker-0')
expect(Gitlab::Chaos).to receive(:run_gc).and_return(gc_stat)
post :gc
expect(response).to have_gitlab_http_status(:ok)
expect(response_json['worker_id']).to eq('worker-0')
expect(response_json['gc_stat']).to eq(gc_stat)
end
end
def response_json
Gitlab::Json.parse(response.body)
end
end
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