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 +4 -4
- data/lib/prometheus/client/helper/entry_parser.rb +32 -0
- data/lib/prometheus/client/helper/file_locker.rb +46 -0
- data/lib/prometheus/client/helper/mmaped_file.rb +8 -92
- data/lib/prometheus/client/helper/plain_file.rb +19 -0
- data/lib/prometheus/client/mmaped_dict.rb +9 -12
- data/lib/prometheus/client/mmaped_value.rb +1 -1
- data/lib/prometheus/client/version.rb +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 010d69c130f93c8618f5bd9daafc5f3df0ccb8fa
|
4
|
+
data.tar.gz: ebea17e5c6d034dde9c0660237482ddae73415c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
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::
|
20
|
+
.find { |path| Helper::FileLocker.lock_to_process(path) }
|
36
21
|
end
|
37
22
|
|
38
|
-
def
|
39
|
-
filename = Helper::MmapedFile.
|
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.
|
86
|
+
mmaped_file = Helper::MmapedFile.open_exclusive_file(@file_prefix)
|
87
87
|
|
88
88
|
@@files[@file_prefix] = MmapedDict.new(mmaped_file)
|
89
89
|
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.
|
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-
|
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
|