prometheus-client-mmap 0.7.0.beta18 → 0.7.0.beta19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 125465cb67bfcdcce578b05e2533264d5a6f16bf
4
- data.tar.gz: 8251ad819a49074395451366c33ed4e2e28c7efd
3
+ metadata.gz: 010d69c130f93c8618f5bd9daafc5f3df0ccb8fa
4
+ data.tar.gz: ebea17e5c6d034dde9c0660237482ddae73415c7
5
5
  SHA512:
6
- metadata.gz: e1e6d918da65e60683c55306e74869a5b166ed21a8ba0b0512b11d9f1c817d625541300d06668e294bb99cdf5b3a6feacb24e990e6bf97249c1eadcb7d65fdf0
7
- data.tar.gz: 50f9b80b2f9d2861e18105c6037cac59e8b282aaed402f571d4a75cbc43b2a1221b7c9ac1f6e8eadadefa189b502e4bc3697bd3c1fee6abbfcc98e6ac2f3a698
6
+ metadata.gz: 641ca6e4fb6587f345a340ade98823dd339c2cfc5f2a057d53e8a9f9fdb0f64367c6c51a21b60837cea27bb5d5d8c8fb723c75fcafed9e67d2a22f622d10267a
7
+ data.tar.gz: 447c4af8a99826c37e4c33059cb4753108ee79afe924e01c882c8c08bbef465b9ecf6c7772eaff63dc4dd48adeea50570cd8d7b14c3203453b4317e06d576765
@@ -0,0 +1,32 @@
1
+ module Prometheus
2
+ module Client
3
+ module Helper
4
+ module EntryParser
5
+ def used
6
+ slice(4..7).unpack('l')[0]
7
+ end
8
+
9
+ def entries
10
+ return Enumerator.new {} if used.zero?
11
+
12
+ Enumerator.new do |yielder|
13
+ used_ = used # cache used to avoid unnecessary unpack operations
14
+
15
+ pos = 12 # pid + used + padding offset
16
+ while pos < used_
17
+ data = slice(pos..-1)
18
+ encoded_len, = data.unpack('l')
19
+ padding_len = 8 - (encoded_len + 4) % 8
20
+ value_offset = 4 + encoded_len + padding_len
21
+ pos += value_offset
22
+
23
+ yielder.yield data, encoded_len, value_offset, pos
24
+
25
+ pos += 8
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ module Prometheus
2
+ module Client
3
+ module Helper
4
+ class FileLocker
5
+ class << self
6
+ LOCK_FILE_MUTEX = Mutex.new
7
+
8
+ def lock_to_process(filepath)
9
+ LOCK_FILE_MUTEX.synchronize do
10
+ @file_locks ||= {}
11
+ return false if @file_locks[filepath]
12
+
13
+ file = File.open(filepath, 'w+')
14
+ if file.flock(File::LOCK_NB | File::LOCK_EX)
15
+ @file_locks[filepath] = file
16
+ return true
17
+ else
18
+ return false
19
+ end
20
+ end
21
+ end
22
+
23
+ def unlock(filepath)
24
+ LOCK_FILE_MUTEX.synchronize do
25
+ @file_locks ||= {}
26
+ return false unless @file_locks[filepath]
27
+
28
+ @file_locks.delete(filepath).flock(File::LOCK_UN)
29
+ end
30
+ end
31
+
32
+ def unlock_all
33
+ LOCK_FILE_MUTEX.synchronize do
34
+ @file_locks ||= {}
35
+ @file_locks.values.each do |file|
36
+ file.flock(File::LOCK_UN)
37
+ end
38
+
39
+ @file_locks = {}
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,42 +1,27 @@
1
- require 'prometheus/client'
1
+ require 'prometheus/client/helper/entry_parser'
2
+ require 'prometheus/client/helper/file_locker'
2
3
  require 'mmap'
3
4
 
4
5
  module Prometheus
5
6
  module Client
6
7
  module Helper
7
8
  class MmapedFile < Mmap
8
- class << self
9
- def open_readonly(filepath)
10
- MmapedFile.new(filepath, 'r', Mmap::MAP_PRIVATE)
11
- end
9
+ include EntryParser
12
10
 
11
+ class << self
13
12
  def open(filepath)
14
13
  MmapedFile.new(filepath, 'rw', Mmap::MAP_SHARED)
15
14
  end
16
15
 
17
- def lock_to_process(filepath)
18
- m = open(filepath)
19
- if m.lock_to_process
20
- Kernel.at_exit do
21
- open(filepath).unlock
22
- end
23
- true
24
- else
25
- false
26
- end
27
- ensure
28
- m.close
29
- end
30
-
31
- def ensure_process_exclusive_file(file_prefix = 'mmaped_file')
16
+ def ensure_exclusive_file(file_prefix = 'mmaped_file')
32
17
  (0..Float::INFINITY).lazy
33
18
  .map { |f_num| "#{file_prefix}_#{Prometheus::Client.pid}-#{f_num}.db" }
34
19
  .map { |filename| File.join(Prometheus::Client.configuration.multiprocess_files_dir, filename) }
35
- .find { |path| Helper::MmapedFile.lock_to_process(path) }
20
+ .find { |path| Helper::FileLocker.lock_to_process(path) }
36
21
  end
37
22
 
38
- def open_process_exclusive_file(file_prefix = 'mmaped_file')
39
- filename = Helper::MmapedFile.ensure_process_exclusive_file(file_prefix)
23
+ def open_exclusive_file(file_prefix = 'mmaped_file')
24
+ filename = Helper::MmapedFile.ensure_exclusive_file(file_prefix)
40
25
  open(filename)
41
26
  end
42
27
  end
@@ -55,70 +40,10 @@ module Prometheus
55
40
  super(filepath, mode, protection, options)
56
41
  end
57
42
 
58
- def pid
59
- self[0..3].unpack('l')[0]
60
- end
61
-
62
- def pid=(value)
63
- self[0..3] = [value].pack('l')
64
- end
65
-
66
- def used
67
- self[4..7].unpack('l')[0]
68
- end
69
-
70
43
  def used=(value)
71
44
  self[4..7] = [value].pack('l')
72
45
  end
73
46
 
74
- def locked_to_process?
75
- pid > 0 && pid_alive?(pid)
76
- end
77
-
78
- def lock_owner?
79
- pid == Process.pid
80
- end
81
-
82
- def lock_to_process
83
- return true if lock_owner?
84
-
85
- if locked_to_process?
86
- false
87
- else
88
- self.pid = Process.pid
89
-
90
- # check if PID was correctly written
91
- lock_owner?
92
- end
93
- end
94
-
95
- def unlock
96
- return unless lock_owner?
97
-
98
- self.pid = 0
99
- end
100
-
101
- def entries
102
- return Enumerator.new {} if used.zero?
103
-
104
- Enumerator.new do |yielder|
105
- used_ = used # cache used to avoid unnecessary unpack operations
106
-
107
- pos = 12 # pid + used + padding offset
108
- while pos < used_
109
- data = slice(pos..-1)
110
- encoded_len, = data.unpack('l')
111
- padding_len = 8 - (encoded_len + 4) % 8
112
- value_offset = 4 + encoded_len + padding_len
113
- pos += value_offset
114
-
115
- yielder.yield data, encoded_len, value_offset, pos
116
-
117
- pos += 8
118
- end
119
- end
120
- end
121
-
122
47
  def add_entry(data, value)
123
48
  self.used = 12 if used.zero?
124
49
 
@@ -146,15 +71,6 @@ module Prometheus
146
71
  def initial_mmap_file_size
147
72
  Prometheus::Client.configuration.initial_mmap_file_size
148
73
  end
149
-
150
- def pid_alive?(pid)
151
- begin
152
- Process.getpgid(pid)
153
- true
154
- rescue Errno::ESRCH
155
- false
156
- end
157
- end
158
74
  end
159
75
  end
160
76
  end
@@ -0,0 +1,19 @@
1
+ require 'prometheus/client/helper/entry_parser'
2
+
3
+ module Prometheus
4
+ module Client
5
+ module Helper
6
+ class PlainFile
7
+ include EntryParser
8
+
9
+ def initialize(filepath)
10
+ @data = File.read(filepath, mode: 'rb')
11
+ end
12
+
13
+ def slice(*args)
14
+ @data.slice(*args)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,5 @@
1
1
  require 'prometheus/client/helper/mmaped_file'
2
+ require 'prometheus/client/helper/plain_file'
2
3
  require 'prometheus/client'
3
4
 
4
5
  module Prometheus
@@ -17,6 +18,13 @@ module Prometheus
17
18
  MINIMUM_SIZE = 8
18
19
  attr_reader :m, :used, :positions
19
20
 
21
+ def self.read_all_values(f)
22
+ Helper::PlainFile.new(f).entries.map do |data, encoded_len, value_offset, _|
23
+ encoded, value = data.unpack(format('@4A%d@%dd', encoded_len, value_offset))
24
+ [encoded, value]
25
+ end
26
+ end
27
+
20
28
  def initialize(m)
21
29
  @mutex = Mutex.new
22
30
 
@@ -33,18 +41,6 @@ module Prometheus
33
41
  raise ParsingError, "exception #{e} while processing metrics file #{path}"
34
42
  end
35
43
 
36
- # Yield (key, value). No locking is performed.
37
- def self.read_all_values(f)
38
- m = Helper::MmapedFile.open(f)
39
-
40
- m.entries.map do |data, encoded_len, value_offset, _|
41
- encoded, value = data.unpack(format('@4A%d@%dd', encoded_len, value_offset))
42
- [encoded, value]
43
- end
44
- ensure
45
- m.munmap
46
- end
47
-
48
44
  def read_value(key)
49
45
  @mutex.synchronize do
50
46
  init_value(key) unless @positions.key?(key)
@@ -68,6 +64,7 @@ module Prometheus
68
64
  end
69
65
 
70
66
  def close
67
+ @m.sync
71
68
  @m.close
72
69
  rescue TypeError => e
73
70
  Prometheus::Client.logger.warn("munmap raised error #{e}")
@@ -83,7 +83,7 @@ module Prometheus
83
83
  unless @file.nil?
84
84
  @file.close
85
85
  end
86
- mmaped_file = Helper::MmapedFile.open_process_exclusive_file(@file_prefix)
86
+ mmaped_file = Helper::MmapedFile.open_exclusive_file(@file_prefix)
87
87
 
88
88
  @@files[@file_prefix] = MmapedDict.new(mmaped_file)
89
89
  end
@@ -1,5 +1,5 @@
1
1
  module Prometheus
2
2
  module Client
3
- VERSION = '0.7.0.beta18'
3
+ VERSION = '0.7.0.beta19'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus-client-mmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0.beta18
4
+ version: 0.7.0.beta19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Schmidt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-30 00:00:00.000000000 Z
11
+ date: 2017-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mmap2
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 2.2.7
33
+ - !ruby/object:Gem::Dependency
34
+ name: gem_publisher
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.1.1
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 1.1.1
33
47
  description:
34
48
  email:
35
49
  - ts@soundcloud.com
@@ -44,8 +58,11 @@ files:
44
58
  - lib/prometheus/client/counter.rb
45
59
  - lib/prometheus/client/formats/text.rb
46
60
  - lib/prometheus/client/gauge.rb
61
+ - lib/prometheus/client/helper/entry_parser.rb
62
+ - lib/prometheus/client/helper/file_locker.rb
47
63
  - lib/prometheus/client/helper/json_parser.rb
48
64
  - lib/prometheus/client/helper/mmaped_file.rb
65
+ - lib/prometheus/client/helper/plain_file.rb
49
66
  - lib/prometheus/client/histogram.rb
50
67
  - lib/prometheus/client/label_set_validator.rb
51
68
  - lib/prometheus/client/metric.rb