lib/prometheus/client/helper/mmaped_file.rb in prometheus-client-mmap-0.7.0.beta18 vs lib/prometheus/client/helper/mmaped_file.rb in prometheus-client-mmap-0.7.0.beta19

- old
+ new

@@ -1,44 +1,29 @@ -require 'prometheus/client' +require 'prometheus/client/helper/entry_parser' +require 'prometheus/client/helper/file_locker' require 'mmap' module Prometheus module Client module Helper class MmapedFile < Mmap - class << self - def open_readonly(filepath) - MmapedFile.new(filepath, 'r', Mmap::MAP_PRIVATE) - end + include EntryParser + class << self def open(filepath) MmapedFile.new(filepath, 'rw', Mmap::MAP_SHARED) end - def lock_to_process(filepath) - m = open(filepath) - if m.lock_to_process - Kernel.at_exit do - open(filepath).unlock - end - true - else - false - end - ensure - m.close - end - - def ensure_process_exclusive_file(file_prefix = 'mmaped_file') + def ensure_exclusive_file(file_prefix = 'mmaped_file') (0..Float::INFINITY).lazy .map { |f_num| "#{file_prefix}_#{Prometheus::Client.pid}-#{f_num}.db" } .map { |filename| File.join(Prometheus::Client.configuration.multiprocess_files_dir, filename) } - .find { |path| Helper::MmapedFile.lock_to_process(path) } + .find { |path| Helper::FileLocker.lock_to_process(path) } end - def open_process_exclusive_file(file_prefix = 'mmaped_file') - filename = Helper::MmapedFile.ensure_process_exclusive_file(file_prefix) + def open_exclusive_file(file_prefix = 'mmaped_file') + filename = Helper::MmapedFile.ensure_exclusive_file(file_prefix) open(filename) end end MINIMUM_SIZE = 8 @@ -53,74 +38,14 @@ end super(filepath, mode, protection, options) end - def pid - self[0..3].unpack('l')[0] - end - - def pid=(value) - self[0..3] = [value].pack('l') - end - - def used - self[4..7].unpack('l')[0] - end - def used=(value) self[4..7] = [value].pack('l') end - def locked_to_process? - pid > 0 && pid_alive?(pid) - end - - def lock_owner? - pid == Process.pid - end - - def lock_to_process - return true if lock_owner? - - if locked_to_process? - false - else - self.pid = Process.pid - - # check if PID was correctly written - lock_owner? - end - end - - def unlock - return unless lock_owner? - - self.pid = 0 - end - - def entries - return Enumerator.new {} if used.zero? - - Enumerator.new do |yielder| - used_ = used # cache used to avoid unnecessary unpack operations - - pos = 12 # pid + used + padding offset - while pos < used_ - data = slice(pos..-1) - encoded_len, = data.unpack('l') - padding_len = 8 - (encoded_len + 4) % 8 - value_offset = 4 + encoded_len + padding_len - pos += value_offset - - yielder.yield data, encoded_len, value_offset, pos - - pos += 8 - end - end - end - def add_entry(data, value) self.used = 12 if used.zero? # Pad to be 8-byte aligned. padded = data + (' ' * (8 - (data.length + 4) % 8)) @@ -143,18 +68,9 @@ private def initial_mmap_file_size Prometheus::Client.configuration.initial_mmap_file_size - end - - def pid_alive?(pid) - begin - Process.getpgid(pid) - true - rescue Errno::ESRCH - false - end end end end end end