prometheus-client-mmap 0.25.0 → 1.1.1

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -1
  3. data/README.md +32 -28
  4. data/ext/fast_mmaped_file_rs/Cargo.lock +195 -234
  5. data/ext/fast_mmaped_file_rs/Cargo.toml +7 -7
  6. data/ext/fast_mmaped_file_rs/extconf.rb +1 -3
  7. data/ext/fast_mmaped_file_rs/src/file_info.rs +51 -1
  8. data/ext/fast_mmaped_file_rs/src/mmap/inner.rs +0 -10
  9. data/ext/fast_mmaped_file_rs/src/mmap.rs +2 -5
  10. data/lib/prometheus/client/configuration.rb +1 -2
  11. data/lib/prometheus/client/formats/text.rb +1 -12
  12. data/lib/prometheus/client/helper/mmaped_file.rb +3 -14
  13. data/lib/prometheus/client/label_set_validator.rb +1 -2
  14. data/lib/prometheus/client/rack/exporter.rb +1 -3
  15. data/lib/prometheus/client/support/puma.rb +44 -0
  16. data/lib/prometheus/client/version.rb +1 -1
  17. metadata +9 -47
  18. data/ext/fast_mmaped_file/extconf.rb +0 -30
  19. data/ext/fast_mmaped_file/fast_mmaped_file.c +0 -122
  20. data/ext/fast_mmaped_file/file_format.c +0 -5
  21. data/ext/fast_mmaped_file/file_format.h +0 -11
  22. data/ext/fast_mmaped_file/file_parsing.c +0 -195
  23. data/ext/fast_mmaped_file/file_parsing.h +0 -27
  24. data/ext/fast_mmaped_file/file_reading.c +0 -102
  25. data/ext/fast_mmaped_file/file_reading.h +0 -30
  26. data/ext/fast_mmaped_file/globals.h +0 -14
  27. data/ext/fast_mmaped_file/mmap.c +0 -438
  28. data/ext/fast_mmaped_file/mmap.h +0 -61
  29. data/ext/fast_mmaped_file/rendering.c +0 -199
  30. data/ext/fast_mmaped_file/rendering.h +0 -8
  31. data/ext/fast_mmaped_file/utils.c +0 -56
  32. data/ext/fast_mmaped_file/utils.h +0 -22
  33. data/ext/fast_mmaped_file/value_access.c +0 -242
  34. data/ext/fast_mmaped_file/value_access.h +0 -15
  35. data/lib/prometheus/client/helper/loader.rb +0 -40
  36. data/vendor/c/hashmap/.gitignore +0 -52
  37. data/vendor/c/hashmap/LICENSE +0 -21
  38. data/vendor/c/hashmap/README.md +0 -90
  39. data/vendor/c/hashmap/_config.yml +0 -1
  40. data/vendor/c/hashmap/src/hashmap.c +0 -692
  41. data/vendor/c/hashmap/src/hashmap.h +0 -267
  42. data/vendor/c/hashmap/test/Makefile +0 -22
  43. data/vendor/c/hashmap/test/hashmap_test.c +0 -608
  44. data/vendor/c/jsmn/.travis.yml +0 -4
  45. data/vendor/c/jsmn/LICENSE +0 -20
  46. data/vendor/c/jsmn/Makefile +0 -41
  47. data/vendor/c/jsmn/README.md +0 -168
  48. data/vendor/c/jsmn/example/jsondump.c +0 -126
  49. data/vendor/c/jsmn/example/simple.c +0 -76
  50. data/vendor/c/jsmn/jsmn.c +0 -314
  51. data/vendor/c/jsmn/jsmn.h +0 -76
  52. data/vendor/c/jsmn/library.json +0 -16
  53. data/vendor/c/jsmn/test/test.h +0 -27
  54. data/vendor/c/jsmn/test/tests.c +0 -407
  55. data/vendor/c/jsmn/test/testutil.h +0 -94
@@ -6,26 +6,26 @@ edition = "2021"
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
7
 
8
8
  [dependencies]
9
- hashbrown = "0.13"
9
+ hashbrown = "0.14"
10
10
  libc = "0.2"
11
- magnus = { git = "https://github.com/matsadler/magnus", branch = "main", features = ["rb-sys"] }
12
- memmap2 = "0.5"
11
+ magnus = { version = "0.6", features = ["rb-sys"] }
12
+ memmap2 = "0.9"
13
13
  # v0.26 cannot be built on CentOS 7 https://github.com/nix-rust/nix/issues/1972
14
14
  nix = { version = "0.25", features = ["mman"] } # mman used for MsFlags
15
- rb-sys = "0.9"
15
+ rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
16
16
  serde = { version = "1.0", features = ["derive"] }
17
17
  serde_json = { version = "1.0", features = ["raw_value"] }
18
18
  smallvec = { version = "1.10", features = ["serde"] }
19
19
  thiserror = "1.0"
20
20
 
21
21
  [dev-dependencies]
22
- bstr = "1.4"
22
+ bstr = "1.9"
23
23
  indoc = "2.0"
24
24
  # We need the `embed` feature to run tests, but this triggers failures when building as a Gem.
25
- magnus = { git = "https://github.com/matsadler/magnus", branch = "main", features = ["rb-sys","embed"] }
25
+ magnus = { version = "0.6", features = ["rb-sys","embed"] }
26
26
  rand = "0.8"
27
27
  sha2 = "0.10"
28
- tempfile = "3.5"
28
+ tempfile = "3.9"
29
29
 
30
30
  [build-dependencies]
31
31
  rb-sys-env = "0.1"
@@ -24,7 +24,5 @@ if find_executable('rustc')
24
24
  ARGV = trimmed_argv
25
25
  end
26
26
  else
27
- puts 'rustc not found, skipping Rust extension.'
28
-
29
- File.write('Makefile', dummy_makefile($srcdir).join(''))
27
+ raise 'rustc not found. prometheus-client-mmap now requires Rust.'
30
28
  end
@@ -91,6 +91,11 @@ impl FileInfo {
91
91
 
92
92
  match self.file.read_to_end(buf) {
93
93
  Ok(n) if n == self.len => Ok(()),
94
+ // A worker may expand the file between our `stat` and `read`, no harm done.
95
+ Ok(n) if n > self.len => {
96
+ self.len = n;
97
+ Ok(())
98
+ }
94
99
  Ok(_) => Err(MmapError::io(
95
100
  "read",
96
101
  &self.path,
@@ -106,6 +111,8 @@ mod test {
106
111
  use magnus::{eval, RArray, Symbol};
107
112
  use rand::{thread_rng, Rng};
108
113
  use sha2::{Digest, Sha256};
114
+ use std::fs;
115
+ use std::io::Write;
109
116
 
110
117
  use super::*;
111
118
  use crate::testhelper::TestFile;
@@ -165,7 +172,7 @@ mod test {
165
172
 
166
173
  let mut info = FileInfo {
167
174
  file,
168
- path,
175
+ path: path.clone(),
169
176
  len: buf.len(),
170
177
  multiprocess_mode: Symbol::new("puma"),
171
178
  type_: Symbol::new("max"),
@@ -187,4 +194,47 @@ mod test {
187
194
 
188
195
  assert_eq!(in_hash, out_hash, "content hashes");
189
196
  }
197
+
198
+ #[test]
199
+ fn test_read_from_file_resized() {
200
+ let _cleanup = unsafe { magnus::embed::init() };
201
+ let ruby = magnus::Ruby::get().unwrap();
202
+ crate::init(&ruby).unwrap();
203
+
204
+ const BUF_LEN: usize = 1 << 14; // 16KiB
205
+
206
+ // Create a buffer with random data.
207
+ let mut buf = vec![0u8; BUF_LEN];
208
+ thread_rng().fill(buf.as_mut_slice());
209
+
210
+ let TestFile {
211
+ file,
212
+ path,
213
+ dir: _dir,
214
+ } = TestFile::new(&buf);
215
+
216
+ let mut info = FileInfo {
217
+ file,
218
+ path: path.clone(),
219
+ len: buf.len(),
220
+ multiprocess_mode: Symbol::new("puma"),
221
+ type_: Symbol::new("max"),
222
+ pid: "worker-0_0".to_string(),
223
+ };
224
+
225
+ let mut resized_file = fs::OpenOptions::new()
226
+ .write(true)
227
+ .append(true)
228
+ .open(path)
229
+ .unwrap();
230
+
231
+ // Write data to file after it has been `stat`ed in the
232
+ // constructor.
233
+ resized_file.write_all(&[1; 1024]).unwrap();
234
+
235
+ let mut out_buf = Vec::new();
236
+ info.read_from_file(&mut out_buf).unwrap();
237
+
238
+ assert_eq!(BUF_LEN + 1024, info.len, "resized file updated len");
239
+ }
190
240
  }
@@ -224,16 +224,6 @@ impl InnerMmap {
224
224
  }
225
225
  }
226
226
 
227
- /// Truncate the mmapped file to the end of the metrics data.
228
- pub fn truncate_file(&mut self) -> Result<()> {
229
- // CAST: no-op on 64-bit, widening on 32-bit.
230
- let trunc_len = self.len as u64;
231
-
232
- self.file
233
- .set_len(trunc_len)
234
- .map_err(|e| MmapError::legacy(format!("truncate: {e}"), RubyError::Type))
235
- }
236
-
237
227
  /// Load the `used` header containing the size of the metrics data written.
238
228
  pub fn load_used(&self) -> Result<u32> {
239
229
  match read_u32(self.map.as_ref(), 0) {
@@ -225,9 +225,6 @@ impl MmapedFile {
225
225
  let rs_self = &*rb_self;
226
226
 
227
227
  rs_self.inner_mut(|inner| {
228
- // truncate file to actual used size
229
- inner.truncate_file()?;
230
-
231
228
  // We are about to release the backing mmap for Ruby's String
232
229
  // objects. If Ruby attempts to read from them the program will
233
230
  // segfault. We update the length of all Strings to zero so Ruby
@@ -507,14 +504,14 @@ impl MmapedFile {
507
504
  match file.seek(SeekFrom::Start(len - 1)) {
508
505
  Ok(_) => {}
509
506
  Err(_) => {
510
- return Err(MmapError::WithErrno(format!("Can't lseek {}", len - 1)));
507
+ return Err(MmapError::with_errno(format!("Can't lseek {}", len - 1)));
511
508
  }
512
509
  }
513
510
 
514
511
  match file.write(&[0x0]) {
515
512
  Ok(1) => {}
516
513
  _ => {
517
- return Err(MmapError::WithErrno(format!(
514
+ return Err(MmapError::with_errno(format!(
518
515
  "Can't extend {}",
519
516
  path.display()
520
517
  )));
@@ -7,14 +7,13 @@ require 'tmpdir'
7
7
  module Prometheus
8
8
  module Client
9
9
  class Configuration
10
- attr_accessor :value_class, :multiprocess_files_dir, :initial_mmap_file_size, :logger, :pid_provider, :rust_multiprocess_metrics
10
+ attr_accessor :value_class, :multiprocess_files_dir, :initial_mmap_file_size, :logger, :pid_provider
11
11
 
12
12
  def initialize
13
13
  @value_class = ::Prometheus::Client::MmapedValue
14
14
  @initial_mmap_file_size = ::Prometheus::Client::PageSize.page_size(fallback_page_size: 4096)
15
15
  @logger = Logger.new($stdout)
16
16
  @pid_provider = Process.method(:pid)
17
- @rust_multiprocess_metrics = ENV.fetch('prometheus_rust_multiprocess_metrics', nil) == 'true'
18
17
  @multiprocess_files_dir = ENV.fetch('prometheus_multiproc_dir') do
19
18
  Dir.mktmpdir("prometheus-mmap")
20
19
  end
@@ -1,6 +1,5 @@
1
1
  require 'prometheus/client/uses_value_type'
2
2
  require 'prometheus/client/helper/json_parser'
3
- require 'prometheus/client/helper/loader'
4
3
  require 'prometheus/client/helper/plain_file'
5
4
  require 'prometheus/client/helper/metrics_processing'
6
5
  require 'prometheus/client/helper/metrics_representation'
@@ -27,22 +26,12 @@ module Prometheus
27
26
  Helper::MetricsRepresentation.to_text(metrics)
28
27
  end
29
28
 
30
- def marshal_multiprocess(path = Prometheus::Client.configuration.multiprocess_files_dir, use_rust: false)
29
+ def marshal_multiprocess(path = Prometheus::Client.configuration.multiprocess_files_dir)
31
30
  file_list = Dir.glob(File.join(path, '*.db')).sort
32
31
  .map {|f| Helper::PlainFile.new(f) }
33
32
  .map {|f| [f.filepath, f.multiprocess_mode.to_sym, f.type.to_sym, f.pid] }
34
33
 
35
- if use_rust && Prometheus::Client::Helper::Loader.rust_impl_available?
36
34
  FastMmapedFileRs.to_metrics(file_list.to_a)
37
- else
38
- FastMmapedFile.to_metrics(file_list.to_a)
39
- end
40
- end
41
-
42
- def rust_impl_available?
43
- return @rust_available unless @rust_available.nil?
44
-
45
- check_for_rust
46
35
  end
47
36
 
48
37
  private
@@ -1,29 +1,18 @@
1
1
  require 'prometheus/client/helper/entry_parser'
2
2
  require 'prometheus/client/helper/file_locker'
3
- require 'prometheus/client/helper/loader'
4
3
 
5
4
  # load precompiled extension if available
6
5
  begin
7
6
  ruby_version = /(\d+\.\d+)/.match(RUBY_VERSION)
8
- require_relative "../../../#{ruby_version}/fast_mmaped_file"
7
+ require_relative "../../../#{ruby_version}/fast_mmaped_file_rs"
9
8
  rescue LoadError
10
- require 'fast_mmaped_file'
9
+ require 'fast_mmaped_file_rs'
11
10
  end
12
11
 
13
12
  module Prometheus
14
13
  module Client
15
14
  module Helper
16
- # We can't check `Prometheus::Client.configuration` as this creates a circular dependency
17
- if (ENV.fetch('prometheus_rust_mmaped_file', nil) == "true" &&
18
- Prometheus::Client::Helper::Loader.rust_impl_available?)
19
- class MmapedFile < FastMmapedFileRs
20
- end
21
- else
22
- class MmapedFile < FastMmapedFile
23
- end
24
- end
25
-
26
- class MmapedFile
15
+ class MmapedFile < FastMmapedFileRs
27
16
  include EntryParser
28
17
 
29
18
  attr_reader :filepath, :size
@@ -5,8 +5,7 @@ module Prometheus
5
5
  # LabelSetValidator ensures that all used label sets comply with the
6
6
  # Prometheus specification.
7
7
  class LabelSetValidator
8
- # TODO: we might allow setting :instance in the future
9
- RESERVED_LABELS = [:job, :instance].freeze
8
+ RESERVED_LABELS = [].freeze
10
9
 
11
10
  class LabelSetError < StandardError; end
12
11
  class InvalidLabelSetError < LabelSetError; end
@@ -62,10 +62,8 @@ module Prometheus
62
62
  end
63
63
 
64
64
  def respond_with(format)
65
- rust_enabled = Prometheus::Client.configuration.rust_multiprocess_metrics
66
-
67
65
  response = if Prometheus::Client.configuration.value_class.multiprocess
68
- format.marshal_multiprocess(use_rust: rust_enabled)
66
+ format.marshal_multiprocess
69
67
  else
70
68
  format.marshal
71
69
  end
@@ -0,0 +1,44 @@
1
+ module Prometheus
2
+ module Client
3
+ module Support
4
+ module Puma
5
+ extend self
6
+
7
+ def worker_pid_provider
8
+ wid = worker_id
9
+ if wid = worker_id
10
+ wid
11
+ else
12
+ "process_id_#{Process.pid}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def object_based_worker_id
19
+ return unless defined?(::Puma::Cluster::Worker)
20
+
21
+ workers = ObjectSpace.each_object(::Puma::Cluster::Worker)
22
+ return if workers.nil?
23
+
24
+ workers_first = workers.first
25
+ workers_first.index unless workers_first.nil?
26
+ end
27
+
28
+ def program_name
29
+ $PROGRAM_NAME
30
+ end
31
+
32
+ def worker_id
33
+ if matchdata = program_name.match(/puma.*cluster worker ([0-9]+):/)
34
+ "puma_#{matchdata[1]}"
35
+ elsif object_worker_id = object_based_worker_id
36
+ "puma_#{object_worker_id}"
37
+ elsif program_name.include?('puma')
38
+ 'puma_master'
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,5 @@
1
1
  module Prometheus
2
2
  module Client
3
- VERSION = '0.25.0'.freeze
3
+ VERSION = '1.1.1'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus-client-mmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Schmidt
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2023-06-15 00:00:00.000000000 Z
14
+ date: 2024-01-30 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rb_sys
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - "~>"
21
21
  - !ruby/object:Gem::Version
22
- version: '0.9'
22
+ version: 0.9.86
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '0.9'
29
+ version: 0.9.86
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: fuzzbert
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -95,14 +95,14 @@ dependencies:
95
95
  requirements:
96
96
  - - "~>"
97
97
  - !ruby/object:Gem::Version
98
- version: 1.3.0
98
+ version: 1.4.0
99
99
  type: :development
100
100
  prerelease: false
101
101
  version_requirements: !ruby/object:Gem::Requirement
102
102
  requirements:
103
103
  - - "~>"
104
104
  - !ruby/object:Gem::Version
105
- version: 1.3.0
105
+ version: 1.4.0
106
106
  - !ruby/object:Gem::Dependency
107
107
  name: ruby-prof
108
108
  requirement: !ruby/object:Gem::Requirement
@@ -125,29 +125,11 @@ email:
125
125
  - wchandler@gitlab.com
126
126
  executables: []
127
127
  extensions:
128
- - ext/fast_mmaped_file/extconf.rb
129
128
  - ext/fast_mmaped_file_rs/extconf.rb
130
129
  extra_rdoc_files: []
131
130
  files:
132
131
  - ".tool-versions"
133
132
  - README.md
134
- - ext/fast_mmaped_file/extconf.rb
135
- - ext/fast_mmaped_file/fast_mmaped_file.c
136
- - ext/fast_mmaped_file/file_format.c
137
- - ext/fast_mmaped_file/file_format.h
138
- - ext/fast_mmaped_file/file_parsing.c
139
- - ext/fast_mmaped_file/file_parsing.h
140
- - ext/fast_mmaped_file/file_reading.c
141
- - ext/fast_mmaped_file/file_reading.h
142
- - ext/fast_mmaped_file/globals.h
143
- - ext/fast_mmaped_file/mmap.c
144
- - ext/fast_mmaped_file/mmap.h
145
- - ext/fast_mmaped_file/rendering.c
146
- - ext/fast_mmaped_file/rendering.h
147
- - ext/fast_mmaped_file/utils.c
148
- - ext/fast_mmaped_file/utils.h
149
- - ext/fast_mmaped_file/value_access.c
150
- - ext/fast_mmaped_file/value_access.h
151
133
  - ext/fast_mmaped_file_rs/.cargo/config.toml
152
134
  - ext/fast_mmaped_file_rs/Cargo.lock
153
135
  - ext/fast_mmaped_file_rs/Cargo.toml
@@ -174,7 +156,6 @@ files:
174
156
  - lib/prometheus/client/helper/entry_parser.rb
175
157
  - lib/prometheus/client/helper/file_locker.rb
176
158
  - lib/prometheus/client/helper/json_parser.rb
177
- - lib/prometheus/client/helper/loader.rb
178
159
  - lib/prometheus/client/helper/metrics_processing.rb
179
160
  - lib/prometheus/client/helper/metrics_representation.rb
180
161
  - lib/prometheus/client/helper/mmaped_file.rb
@@ -191,29 +172,10 @@ files:
191
172
  - lib/prometheus/client/registry.rb
192
173
  - lib/prometheus/client/simple_value.rb
193
174
  - lib/prometheus/client/summary.rb
175
+ - lib/prometheus/client/support/puma.rb
194
176
  - lib/prometheus/client/support/unicorn.rb
195
177
  - lib/prometheus/client/uses_value_type.rb
196
178
  - lib/prometheus/client/version.rb
197
- - vendor/c/hashmap/.gitignore
198
- - vendor/c/hashmap/LICENSE
199
- - vendor/c/hashmap/README.md
200
- - vendor/c/hashmap/_config.yml
201
- - vendor/c/hashmap/src/hashmap.c
202
- - vendor/c/hashmap/src/hashmap.h
203
- - vendor/c/hashmap/test/Makefile
204
- - vendor/c/hashmap/test/hashmap_test.c
205
- - vendor/c/jsmn/.travis.yml
206
- - vendor/c/jsmn/LICENSE
207
- - vendor/c/jsmn/Makefile
208
- - vendor/c/jsmn/README.md
209
- - vendor/c/jsmn/example/jsondump.c
210
- - vendor/c/jsmn/example/simple.c
211
- - vendor/c/jsmn/jsmn.c
212
- - vendor/c/jsmn/jsmn.h
213
- - vendor/c/jsmn/library.json
214
- - vendor/c/jsmn/test/test.h
215
- - vendor/c/jsmn/test/tests.c
216
- - vendor/c/jsmn/test/testutil.h
217
179
  homepage: https://gitlab.com/gitlab-org/prometheus-client-mmap
218
180
  licenses:
219
181
  - Apache-2.0
@@ -236,6 +198,6 @@ requirements: []
236
198
  rubygems_version: 3.3.26
237
199
  signing_key:
238
200
  specification_version: 4
239
- summary: A suite of instrumentation metric primitivesthat can be exposed through a
240
- web services interface.
201
+ summary: A suite of instrumentation metric primitives that can be exposed through
202
+ a web services interface.
241
203
  test_files: []
@@ -1,30 +0,0 @@
1
- require 'mkmf'
2
- require 'fileutils'
3
-
4
- $CFLAGS << ' -std=c99 -D_POSIX_C_SOURCE=200809L -Wall -Wextra'
5
-
6
- if enable_config('fail-on-warning')
7
- $CFLAGS << ' -Werror'
8
- end
9
-
10
- if enable_config('debug')
11
- $CFLAGS << ' -O0 -g'
12
- end
13
-
14
- if enable_config('address-sanitizer')
15
- $CFLAGS << ' -O -fsanitize=address -fno-omit-frame-pointer -g'
16
- end
17
-
18
- CONFIG['warnflags'].slice!(/ -Wdeclaration-after-statement/)
19
-
20
- cwd = File.expand_path(File.dirname(__FILE__))
21
- vendor_dir = File.join(cwd, '../../vendor/c')
22
- src_dir = File.join(cwd, '../../ext/fast_mmaped_file')
23
-
24
- src_files = %W[#{vendor_dir}/jsmn/jsmn.c #{vendor_dir}/hashmap/src/hashmap.c]
25
- FileUtils.cp(src_files, src_dir)
26
-
27
- $INCFLAGS << " -I#{vendor_dir}/jsmn -I#{vendor_dir}/hashmap/src"
28
-
29
- dir_config('fast_mmaped_file')
30
- create_makefile('fast_mmaped_file')
@@ -1,122 +0,0 @@
1
- #include <errno.h>
2
- #include <hashmap.h>
3
- #include <jsmn.h>
4
- #include <ruby.h>
5
- #include <ruby/intern.h>
6
- #include <sys/mman.h>
7
-
8
- #include "file_parsing.h"
9
- #include "file_reading.h"
10
- #include "globals.h"
11
- #include "mmap.h"
12
- #include "rendering.h"
13
- #include "utils.h"
14
- #include "value_access.h"
15
-
16
- VALUE MMAPED_FILE = Qnil;
17
-
18
- ID sym_min;
19
- ID sym_max;
20
- ID sym_livesum;
21
- ID sym_gauge;
22
- ID sym_pid;
23
- ID sym_samples;
24
-
25
- VALUE prom_eParsingError;
26
-
27
- int aggregate_files(struct hashmap *map, VALUE list_of_files) {
28
- buffer_t reading_buffer;
29
- memset(&reading_buffer, 0, sizeof(buffer_t));
30
-
31
- for (int i = 0; i < RARRAY_LEN(list_of_files); i++) {
32
- VALUE params = RARRAY_PTR(list_of_files)[i];
33
- file_t file;
34
-
35
- if (!file_open_from_params(&file, params)) {
36
- buffer_dispose(&reading_buffer);
37
- return 0;
38
- }
39
-
40
- if (!read_from_file(&file, &reading_buffer)) {
41
- buffer_dispose(&reading_buffer);
42
- file_close(&file);
43
- return 0;
44
- }
45
-
46
- if (!process_buffer(&file, &reading_buffer, map)) {
47
- buffer_dispose(&reading_buffer);
48
- file_close(&file);
49
- return 0;
50
- }
51
-
52
- if (!file_close(&file)) {
53
- buffer_dispose(&reading_buffer);
54
- return 0;
55
- }
56
- }
57
-
58
- buffer_dispose(&reading_buffer);
59
- return 1;
60
- }
61
-
62
- VALUE method_to_metrics(VALUE UNUSED(self), VALUE file_list) {
63
- struct hashmap map;
64
- hashmap_setup(&map);
65
-
66
- if (!aggregate_files(&map, file_list)) { // all entries in map are now copies that need to be disposed
67
- hashmap_destroy(&map);
68
- raise_last_exception();
69
- return Qnil;
70
- }
71
-
72
- entry_t **sorted_entries;
73
-
74
- if (!sort_map_entries(&map, &sorted_entries)) {
75
- hashmap_destroy(&map);
76
-
77
- raise_last_exception();
78
- return Qnil;
79
- }
80
-
81
- VALUE rv = rb_str_new("", 0);
82
- if (!entries_to_string(rv, sorted_entries, hashmap_size(&map))) {
83
- free(sorted_entries);
84
- hashmap_destroy(&map);
85
-
86
- raise_last_exception();
87
- return Qnil;
88
- }
89
-
90
- RB_GC_GUARD(file_list); // ensure file list is not GCed before this point
91
- free(sorted_entries);
92
- hashmap_destroy(&map);
93
- return rv;
94
- }
95
-
96
- void Init_fast_mmaped_file() {
97
- sym_gauge = rb_intern("gauge");
98
- sym_min = rb_intern("min");
99
- sym_max = rb_intern("max");
100
- sym_livesum = rb_intern("livesum");
101
- sym_pid = rb_intern("pid");
102
- sym_samples = rb_intern("samples");
103
-
104
- prom_eParsingError = rb_define_class("PrometheusParsingError", rb_eRuntimeError);
105
-
106
- MMAPED_FILE = rb_define_class("FastMmapedFile", rb_cObject);
107
- rb_define_const(MMAPED_FILE, "MAP_SHARED", INT2FIX(MAP_SHARED));
108
-
109
- rb_define_singleton_method(MMAPED_FILE, "to_metrics", method_to_metrics, 1);
110
-
111
- rb_define_alloc_func(MMAPED_FILE, mm_s_alloc);
112
- rb_define_singleton_method(MMAPED_FILE, "new", mm_s_new, -1);
113
- rb_define_method(MMAPED_FILE, "initialize", mm_init, 1);
114
- rb_define_method(MMAPED_FILE, "slice", mm_aref_m, -1);
115
- rb_define_method(MMAPED_FILE, "sync", mm_msync, -1);
116
- rb_define_method(MMAPED_FILE, "munmap", mm_unmap, 0);
117
-
118
- rb_define_method(MMAPED_FILE, "used", method_load_used, 0);
119
- rb_define_method(MMAPED_FILE, "used=", method_save_used, 1);
120
- rb_define_method(MMAPED_FILE, "fetch_entry", method_fetch_entry, 3);
121
- rb_define_method(MMAPED_FILE, "upsert_entry", method_upsert_entry, 3);
122
- }
@@ -1,5 +0,0 @@
1
- #include "file_format.h"
2
-
3
- inline uint32_t padding_length(uint32_t key_length) {
4
- return 8 - (sizeof(uint32_t) + key_length) % 8; // padding | 8 byte aligned
5
- }
@@ -1,11 +0,0 @@
1
- #ifndef FILE_FORMAT_H
2
- #define FILE_FORMAT_H
3
-
4
- #include <stdint.h>
5
-
6
- #define START_POSITION 8
7
- #define INITIAL_SIZE (2 * sizeof(int32_t))
8
-
9
- uint32_t padding_length(uint32_t key_length);
10
-
11
- #endif