lib/prometheus/client/mmaped_value.rb in prometheus-client-mmap-0.7.0.beta34 vs lib/prometheus/client/mmaped_value.rb in prometheus-client-mmap-0.7.0.beta35

- old
+ new

@@ -4,12 +4,13 @@ module Prometheus module Client # A float protected by a mutex backed by a per-process mmaped file. class MmapedValue - @@files = {} VALUE_LOCK = Mutex.new + + @@files = {} @@pid = -1 def initialize(type, metric_name, name, labels, multiprocess_mode = '') @file_prefix = type.to_s @metric_name = metric_name @@ -23,11 +24,11 @@ @mutex = Mutex.new initialize_file end - def increment(amount=1) + def increment(amount = 1) @mutex.synchronize do initialize_file if pid_changed? @value += amount write_value(@key, @value) @@ -54,39 +55,23 @@ def pid_changed? @pid != Process.pid end - def reinitialize - initialize_file if pid_changed? + # method needs to be run in VALUE_LOCK mutex + def unsafe_reinitialize_file(check_pid = true) + unsafe_initialize_file if !check_pid || pid_changed? end - def initialize_file + def self.reset_and_reinitialize VALUE_LOCK.synchronize do - return if @file && !pid_changed? - self.class.reset_on_pid_change + @@pid = Process.pid + @@files = {} - @pid = Process.pid - unless @@files.has_key?(@file_prefix) - unless @file.nil? - @file.close - end - mmaped_file = Helper::MmapedFile.open_exclusive_file(@file_prefix) - - @@files[@file_prefix] = MmapedDict.new(mmaped_file) + ObjectSpace.each_object(MmapedValue).each do |v| + v.unsafe_reinitialize_file(false) end - - @file = @@files[@file_prefix] - labelnames = [] - labelvalues = [] - @labels.each do |k, v| - labelnames << k - labelvalues << v - end - - @key = [@metric_name, @name, labelnames, labelvalues].to_json - @value = read_value(@key) end end def self.reset_on_pid_change if pid_changed? @@ -96,13 +81,13 @@ end def self.reinitialize_on_pid_change VALUE_LOCK.synchronize do reset_on_pid_change - end - ObjectSpace.each_object(MmapedValue, &:reinitialize) + ObjectSpace.each_object(MmapedValue, &:unsafe_reinitialize_file) + end end def self.pid_changed? @@pid != Process.pid end @@ -111,12 +96,48 @@ true end private + def initialize_file + VALUE_LOCK.synchronize do + unsafe_initialize_file + end + end + + def unsafe_initialize_file + self.class.reset_on_pid_change + + @pid = Process.pid + unless @@files.has_key?(@file_prefix) + unless @file.nil? + @file.close + end + mmaped_file = Helper::MmapedFile.open_exclusive_file(@file_prefix) + + @@files[@file_prefix] = MmapedDict.new(mmaped_file) + end + + @file = @@files[@file_prefix] + @key = rebuild_key + + @value = read_value(@key) + end + + + def rebuild_key + labelnames = [] + labelvalues = [] + @labels.each do |k, v| + labelnames << k + labelvalues << v + end + + [@metric_name, @name, labelnames, labelvalues].to_json + end + def write_value(key, val) @file.write_value(key, val) - rescue StandardError => e Prometheus::Client.logger.warn("writing value to #{@file.path} failed with #{e}") Prometheus::Client.logger.debug(e.backtrace.join("\n")) end