Commit 408208bc authored by Pawel Chojnacki's avatar Pawel Chojnacki

Use AtomicFixNum to implement CAS isolated cache update.

i.e.
Using compare and swap we update the expires_at value.
The thread that actually is able to update this value will also set
the cache holding method_call enabled state
parent 5904b033
...@@ -2,7 +2,8 @@ module Gitlab ...@@ -2,7 +2,8 @@ module Gitlab
module Metrics module Metrics
# Class for tracking timing information about method calls # Class for tracking timing information about method calls
class MethodCall class MethodCall
MEASUREMENT_ENABLED_CACHE = Concurrent::AtomicReference.new({ enabled: false, expires_at: Time.now }) MEASUREMENT_ENABLED_CACHE = Concurrent::AtomicBoolean.new(false)
MEASUREMENT_ENABLED_CACHE_EXPIRES_AT = Concurrent::AtomicFixnum.new(Time.now.to_i)
MUTEX = Mutex.new MUTEX = Mutex.new
BASE_LABELS = { module: nil, method: nil }.freeze BASE_LABELS = { module: nil, method: nil }.freeze
attr_reader :real_time, :cpu_time, :call_count, :labels attr_reader :real_time, :cpu_time, :call_count, :labels
...@@ -20,18 +21,14 @@ module Gitlab ...@@ -20,18 +21,14 @@ module Gitlab
end end
def call_measurement_enabled? def call_measurement_enabled?
res = MEASUREMENT_ENABLED_CACHE.update do |cache| expires_at = MEASUREMENT_ENABLED_CACHE_EXPIRES_AT.value
if cache[:expires_at] < Time.now if expires_at < Time.now.to_i
{ if MEASUREMENT_ENABLED_CACHE_EXPIRES_AT.compare_and_set(expires_at, (Time.now + 30.seconds).to_i)
enabled: Feature.get(:prometheus_metrics_method_instrumentation).enabled?, MEASUREMENT_ENABLED_CACHE.value = Feature.get(:prometheus_metrics_method_instrumentation).enabled?
expires_at: Time.now + 5.minutes
}
else
cache
end end
end end
res[:enabled] MEASUREMENT_ENABLED_CACHE.value
end end
# name - The full name of the method (including namespace) such as # name - The full name of the method (including namespace) such as
......
...@@ -21,7 +21,7 @@ describe Gitlab::Metrics::MethodCall do ...@@ -21,7 +21,7 @@ describe Gitlab::Metrics::MethodCall do
context 'prometheus instrumentation is enabled' do context 'prometheus instrumentation is enabled' do
before do before do
allow(Feature.get(:prometheus_metrics_method_instrumentation)).to receive(:enabled?).and_call_original allow(Feature.get(:prometheus_metrics_method_instrumentation)).to receive(:enabled?).and_call_original
described_class::MEASUREMENT_ENABLED_CACHE.set({enabled: false, expires_at: Time.now - 1.second}) described_class::MEASUREMENT_ENABLED_CACHE_EXPIRES_AT.value = Time.now.to_i - 1
Feature.get(:prometheus_metrics_method_instrumentation).enable Feature.get(:prometheus_metrics_method_instrumentation).enable
end end
...@@ -39,12 +39,16 @@ describe Gitlab::Metrics::MethodCall do ...@@ -39,12 +39,16 @@ describe Gitlab::Metrics::MethodCall do
expect(Feature.get(:prometheus_metrics_method_instrumentation)).to have_received(:enabled?).once expect(Feature.get(:prometheus_metrics_method_instrumentation)).to have_received(:enabled?).once
end end
it 'expires feature check cache after 5 minutes' do it 'expires feature check cache after 30 seconds' do
10.times do 10.times do
method_call.measure { 'foo' } method_call.measure { 'foo' }
end end
Timecop.travel(Time.now + 5.minutes) do Timecop.travel(Time.now + 30.seconds) do
method_call.measure { 'foo' }
end
Timecop.travel(Time.now + 31.seconds) do
method_call.measure { 'foo' } method_call.measure { 'foo' }
end end
...@@ -62,7 +66,8 @@ describe Gitlab::Metrics::MethodCall do ...@@ -62,7 +66,8 @@ describe Gitlab::Metrics::MethodCall do
context 'prometheus instrumentation is disabled' do context 'prometheus instrumentation is disabled' do
before do before do
described_class::MEASUREMENT_ENABLED_CACHE.set({enabled: false, expires_at: Time.now}) described_class::MEASUREMENT_ENABLED_CACHE_EXPIRES_AT.value = Time.now.to_i - 1
Feature.get(:prometheus_metrics_method_instrumentation).disable Feature.get(:prometheus_metrics_method_instrumentation).disable
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