Class: Prometheus::EnumeratedStore::PidEnumerator
- Inherits:
-
Object
- Object
- Prometheus::EnumeratedStore::PidEnumerator
- Defined in:
- lib/prometheus/enumerated_store/pid_enumerator.rb
Constant Summary collapse
- MAX_INSTANCES =
1000
Instance Attribute Summary collapse
-
#dir ⇒ Object
readonly
Returns the value of attribute dir.
-
#instances_path ⇒ Object
readonly
Returns the value of attribute instances_path.
-
#lock_path ⇒ Object
readonly
Returns the value of attribute lock_path.
Instance Method Summary collapse
- #alive?(pid) ⇒ Boolean
- #clean_dead_instances(data) ⇒ Object
- #find_minimal_number(data) ⇒ Object
-
#initialize(dir:) ⇒ PidEnumerator
constructor
A new instance of PidEnumerator.
- #obtain_enumerated_number ⇒ Object
- #obtained ⇒ Object
- #read_instances ⇒ Object
- #reset ⇒ Object
- #with_lock ⇒ Object
Constructor Details
#initialize(dir:) ⇒ PidEnumerator
Returns a new instance of PidEnumerator.
15 16 17 18 19 20 21 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 15 def initialize(dir:) @dir = dir @lock_path = File.join(@dir, 'enumetated_instances.lock') @instances_path = File.join(@dir, 'enumetated_instances.json') reset end |
Instance Attribute Details
#dir ⇒ Object (readonly)
Returns the value of attribute dir.
13 14 15 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 13 def dir @dir end |
#instances_path ⇒ Object (readonly)
Returns the value of attribute instances_path.
13 14 15 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 13 def instances_path @instances_path end |
#lock_path ⇒ Object (readonly)
Returns the value of attribute lock_path.
13 14 15 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 13 def lock_path @lock_path end |
Instance Method Details
#alive?(pid) ⇒ Boolean
82 83 84 85 86 87 88 89 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 82 def alive?(pid) return nil if pid <= 1 Process.getpgid(pid) true rescue Errno::ESRCH false end |
#clean_dead_instances(data) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 74 def clean_dead_instances(data) data.select do |pid, num| next nil if num.to_i <= 0 || num.to_i > MAX_INSTANCES alive?(pid.to_i) end end |
#find_minimal_number(data) ⇒ Object
66 67 68 69 70 71 72 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 66 def find_minimal_number(data) values = data.values current = data[Process.pid.to_s] || (1..MAX_INSTANCES).find{|i| !values.include?(i) } raise "Unable to find any number between 1 and #{MAX_INSTANCES}" unless current data[Process.pid.to_s] = current end |
#obtain_enumerated_number ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 51 def obtain_enumerated_number with_lock do |tmpfilename| break @obtained if @obtained # double check-lock raw_data = read_instances data = JSON.parse(raw_data) || {} # set {} if "null" in file data = clean_dead_instances(data) current = find_minimal_number(data) File.write(tmpfilename, data.to_json) # We are inside tmpdir File.rename(tmpfilename, instances_path) current end end |
#obtained ⇒ Object
47 48 49 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 47 def obtained @obtained ||= obtain_enumerated_number end |
#read_instances ⇒ Object
39 40 41 42 43 44 45 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 39 def read_instances raw = File.read(instances_path).strip raw.empty? ? '{}' : raw rescue Errno::ENOENT # there is no file yet '{}' end |
#reset ⇒ Object
23 24 25 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 23 def reset @obtained = nil end |
#with_lock ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/prometheus/enumerated_store/pid_enumerator.rb', line 27 def with_lock File.open(lock_path, File::RDWR | File::CREAT, 0o644) do |file| file.flock(File::LOCK_EX) Dir.chdir(@dir) do tmpfilename = ".tmp-#{$$}-#{rand(0x100000000).to_s(36)}.json" yield(tmpfilename) ensure File.delete(tmpfilename) rescue nil end end end |