prometheus-client-mmap 0.28.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -1
  3. data/README.md +2 -30
  4. data/ext/fast_mmaped_file_rs/extconf.rb +1 -3
  5. data/ext/fast_mmaped_file_rs/src/error.rs +8 -0
  6. data/ext/fast_mmaped_file_rs/src/mmap/inner.rs +38 -13
  7. data/ext/fast_mmaped_file_rs/src/mmap.rs +71 -5
  8. data/lib/prometheus/client/configuration.rb +1 -2
  9. data/lib/prometheus/client/formats/text.rb +1 -12
  10. data/lib/prometheus/client/helper/mmaped_file.rb +3 -14
  11. data/lib/prometheus/client/rack/exporter.rb +1 -3
  12. data/lib/prometheus/client/version.rb +1 -1
  13. metadata +4 -43
  14. data/ext/fast_mmaped_file/extconf.rb +0 -30
  15. data/ext/fast_mmaped_file/fast_mmaped_file.c +0 -122
  16. data/ext/fast_mmaped_file/file_format.c +0 -5
  17. data/ext/fast_mmaped_file/file_format.h +0 -11
  18. data/ext/fast_mmaped_file/file_parsing.c +0 -195
  19. data/ext/fast_mmaped_file/file_parsing.h +0 -27
  20. data/ext/fast_mmaped_file/file_reading.c +0 -102
  21. data/ext/fast_mmaped_file/file_reading.h +0 -30
  22. data/ext/fast_mmaped_file/globals.h +0 -14
  23. data/ext/fast_mmaped_file/mmap.c +0 -428
  24. data/ext/fast_mmaped_file/mmap.h +0 -61
  25. data/ext/fast_mmaped_file/rendering.c +0 -199
  26. data/ext/fast_mmaped_file/rendering.h +0 -8
  27. data/ext/fast_mmaped_file/utils.c +0 -56
  28. data/ext/fast_mmaped_file/utils.h +0 -22
  29. data/ext/fast_mmaped_file/value_access.c +0 -242
  30. data/ext/fast_mmaped_file/value_access.h +0 -15
  31. data/lib/prometheus/client/helper/loader.rb +0 -44
  32. data/vendor/c/hashmap/.gitignore +0 -52
  33. data/vendor/c/hashmap/LICENSE +0 -21
  34. data/vendor/c/hashmap/README.md +0 -90
  35. data/vendor/c/hashmap/_config.yml +0 -1
  36. data/vendor/c/hashmap/src/hashmap.c +0 -692
  37. data/vendor/c/hashmap/src/hashmap.h +0 -267
  38. data/vendor/c/hashmap/test/Makefile +0 -22
  39. data/vendor/c/hashmap/test/hashmap_test.c +0 -608
  40. data/vendor/c/jsmn/.travis.yml +0 -4
  41. data/vendor/c/jsmn/LICENSE +0 -20
  42. data/vendor/c/jsmn/Makefile +0 -41
  43. data/vendor/c/jsmn/README.md +0 -168
  44. data/vendor/c/jsmn/example/jsondump.c +0 -126
  45. data/vendor/c/jsmn/example/simple.c +0 -76
  46. data/vendor/c/jsmn/jsmn.c +0 -314
  47. data/vendor/c/jsmn/jsmn.h +0 -76
  48. data/vendor/c/jsmn/library.json +0 -16
  49. data/vendor/c/jsmn/test/test.h +0 -27
  50. data/vendor/c/jsmn/test/tests.c +0 -407
  51. data/vendor/c/jsmn/test/testutil.h +0 -94
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 397a7f8162a7c2ef33bb35dbc4a1985891e9b96fc492319dfc1b6a8e9ec0cbb7
4
- data.tar.gz: 2848f51578cdd4aabf3e13102f42b7b1f07ffc932a15f84cf2c85b2ef92b6c78
3
+ metadata.gz: 97fc31e7c9aad5a4b25d1d02cc7aa5b44f2a74d05a80776aa6d9f961b51a3631
4
+ data.tar.gz: '010394948353bb52e8aa4cd12dd45f22d3026099ae05b6d600905872ac094fc2'
5
5
  SHA512:
6
- metadata.gz: c61ba2713843070ff41449a82a62ee0cb23502d6194e0c2ad79644e3254178f945aa34f2d6af123115389453c13441bf54c22aab36bf05ef33464e3e06f20b58
7
- data.tar.gz: 9e504a92a22eaa933099786e0858bd6d59539a510a29362756cd1636c423e5b5f742a50ce1dac1f19bcef633d9354b11d3ba19d2d1ad4a99d495be9f7d7c69f4
6
+ metadata.gz: fcd7c42ca842979e64b2e510f18cd9113ace7ab6d68a1f017555defd16940a52aac7a081d86a50654045229f098db2bc53de38e7a47e63edab8ed049b1e32629
7
+ data.tar.gz: b2f6438a636775e0bf902f244fcd58b0c97fbe3f1f46edf593a5838f0db9c35219de452322cf03b627e2053bbc72b81e2ff98ac7f1f2bbdb20e26c53bdce79df
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- rust 1.65.0
1
+ rust 1.73.0
data/README.md CHANGED
@@ -53,19 +53,9 @@ http_requests.increment
53
53
 
54
54
  ## Rust extension
55
55
 
56
- In an effort to improve maintainability, there is now a Rust
56
+ This gem now uses a rewritten Rust extension instead of C.
57
57
  implementation that reads the metric files and outputs the multiprocess
58
- metrics to text. If `rustc` is available, then the Rust extension will
59
- be built automatically. The `use_rust` keyword argument can be used:
60
-
61
- ```ruby
62
- puts Prometheus::Client::Formats::Text.marshal_multiprocess(use_rust: true)
63
- ```
64
-
65
- Starting with v0.26.0, `use_rust` defaults to `true`.
66
-
67
- Note that this parameter will likely be deprecated and removed once the Rust
68
- extension becomes the only supported mode.
58
+ metrics to text. This implementation is significantly faster than the C extension.
69
59
 
70
60
  ### Rack middleware
71
61
 
@@ -219,24 +209,6 @@ Set `prometheus_multiproc_dir` environment variable to the path where you want m
219
209
  prometheus_multiproc_dir=/tmp
220
210
  ```
221
211
 
222
- ### Multiprocess metrics via Rust extension
223
-
224
- By default, the Rust extension will be used to read and write multiprocess
225
- metrics if the `fast_mmaped_file_rs` extension is available. This should
226
- be significantly faster than the C extension.
227
-
228
- If the environment variable `prometheus_rust_multiprocess_metrics=false`
229
- is set or if the `rust_multiprocess_metrics` configuration setting is
230
- `false` , the C extension will be used.
231
-
232
- ### Read and write metrics via Rust extension
233
-
234
- By default, the Rust extension will be used to read and write metrics
235
- from the mmaped file if the `fast_mmaped_file_rs` extension is available.
236
-
237
- To use the C extension, set the environment variable
238
- `prometheus_rust_mmaped_file=false`.
239
-
240
212
  ## Pitfalls
241
213
 
242
214
  ### PID cardinality
@@ -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
@@ -100,6 +100,13 @@ pub enum MmapError {
100
100
  /// No mmap open.
101
101
  #[error("unmapped file")]
102
102
  UnmappedFile,
103
+ /// File length changed by another process.
104
+ #[error("size of {path} {len} does not match previous size {expected_len}. Another process may have modified it.")]
105
+ UnexpectedFileLength {
106
+ path: String,
107
+ len: usize,
108
+ expected_len: usize,
109
+ },
103
110
  /// A custom error message with `strerror(3)` appended.
104
111
  #[error("{0}")]
105
112
  WithErrno(String),
@@ -162,6 +169,7 @@ impl MmapError {
162
169
  MmapError::Other(_) => RubyError::Arg,
163
170
  MmapError::PromParsing(_) => RubyError::PromParsing,
164
171
  MmapError::UnmappedFile => RubyError::Io,
172
+ MmapError::UnexpectedFileLength { .. } => RubyError::Runtime,
165
173
  MmapError::WithErrno(_) => RubyError::Io,
166
174
  }
167
175
  }
@@ -5,7 +5,7 @@ use std::fs::File;
5
5
  use std::mem::size_of;
6
6
  use std::ops::Range;
7
7
  use std::os::unix::prelude::{AsRawFd, RawFd};
8
- use std::path::PathBuf;
8
+ use std::path::{Path, PathBuf};
9
9
 
10
10
  use crate::error::{MmapError, RubyError};
11
11
  use crate::raw_entry::RawEntry;
@@ -34,6 +34,8 @@ pub(super) struct InnerMmap {
34
34
  ///
35
35
  /// Equivalent to `i_mm->t->real` in the C implementation.
36
36
  len: usize,
37
+ /// The length of the file being mmapped at the time of mapping.
38
+ file_len: usize,
37
39
  }
38
40
 
39
41
  impl InnerMmap {
@@ -41,19 +43,12 @@ impl InnerMmap {
41
43
  /// Use when mmapping a file for the first time. When re-mapping a file
42
44
  /// after expanding it the `reestablish` function should be used.
43
45
  pub fn new(path: PathBuf, file: File) -> Result<Self> {
44
- let stat = file.metadata().map_err(|e| {
45
- MmapError::legacy(
46
- format!("Can't stat {}: {e}", path.display()),
47
- RubyError::Arg,
48
- )
49
- })?;
50
-
51
- let file_size = util::cast_chk::<_, usize>(stat.len(), "file length")?;
46
+ let initial_file_len = get_file_len(&path, &file)?;
52
47
 
53
48
  // We need to ensure the underlying file descriptor is at least a page size.
54
49
  // Otherwise, we could get a SIGBUS error if mmap() attempts to read or write
55
50
  // past the file.
56
- let reserve_size = Self::next_page_boundary(file_size)?;
51
+ let reserve_size = Self::next_page_boundary(initial_file_len)?;
57
52
 
58
53
  // Cast: no-op.
59
54
  Self::reserve_mmap_file_bytes(file.as_raw_fd(), reserve_size as off_t).map_err(|e| {
@@ -67,21 +62,23 @@ impl InnerMmap {
67
62
  })?;
68
63
 
69
64
  // Ensure we always have space for the header.
70
- let map_len = file_size.max(HEADER_SIZE);
65
+ let map_len = initial_file_len.max(HEADER_SIZE);
71
66
 
72
67
  // SAFETY: There is the possibility of UB if the file is modified outside of
73
68
  // this program.
74
69
  let map = unsafe { MmapOptions::new().len(map_len).map_mut(&file) }.map_err(|e| {
75
70
  MmapError::legacy(format!("mmap failed ({}): {e}", errno()), RubyError::Arg)
76
71
  })?;
72
+ let file_len = util::cast_chk::<_, usize>(reserve_size, "file length")?;
77
73
 
78
- let len = file_size;
74
+ let len = initial_file_len;
79
75
 
80
76
  Ok(Self {
81
77
  file,
82
78
  path,
83
79
  map,
84
80
  len,
81
+ file_len,
85
82
  })
86
83
  }
87
84
 
@@ -97,12 +94,14 @@ impl InnerMmap {
97
94
  // to the old length at this point if closing the file. Matching C implementation
98
95
  // for now.
99
96
  let len = map_len;
97
+ let file_len = get_file_len(&path, &file)?;
100
98
 
101
99
  Ok(Self {
102
100
  file,
103
101
  path,
104
102
  map,
105
103
  len,
104
+ file_len,
106
105
  })
107
106
  }
108
107
 
@@ -186,7 +185,7 @@ impl InnerMmap {
186
185
  self.len
187
186
  }
188
187
 
189
- /// The total length in bytes of the mmapped file.
188
+ /// The total length in bytes of the mmapped region of the file.
190
189
  ///
191
190
  /// Equivalent to `i_mm->t->len` in the C implementation.
192
191
  #[inline]
@@ -194,6 +193,21 @@ impl InnerMmap {
194
193
  self.map.len()
195
194
  }
196
195
 
196
+ /// `stat` the mmapped file and return its length.
197
+ pub fn check_file_len(&self) -> Result<usize> {
198
+ get_file_len(&self.path, &self.file)
199
+ }
200
+
201
+ /// The length of the file at the time it was mmapped.
202
+ pub fn file_len(&self) -> usize {
203
+ self.file_len
204
+ }
205
+
206
+ /// The path of the mmapped file.
207
+ pub fn path(&self) -> String {
208
+ self.path.to_string_lossy().to_string()
209
+ }
210
+
197
211
  /// Update the length of the mmap considered to be written.
198
212
  pub fn set_len(&mut self, len: usize) {
199
213
  self.len = len;
@@ -312,6 +326,17 @@ impl InnerMmap {
312
326
  }
313
327
  }
314
328
 
329
+ fn get_file_len(path: &Path, file: &File) -> Result<usize> {
330
+ let stat = file.metadata().map_err(|e| {
331
+ MmapError::legacy(
332
+ format!("Can't stat {}: {e}", path.display()),
333
+ RubyError::Arg,
334
+ )
335
+ })?;
336
+
337
+ util::cast_chk::<_, usize>(stat.len(), "file length")
338
+ }
339
+
315
340
  #[cfg(test)]
316
341
  mod test {
317
342
  use nix::unistd::{self, SysconfVar};
@@ -441,17 +441,49 @@ impl MmapedFile {
441
441
  }
442
442
 
443
443
  /// Check that the mmap is large enough to contain the value to be added,
444
- /// and expand it to fit if necessary.
444
+ /// and expand it to fit if necessary. Will return an error if the file
445
+ /// has been resized by another process.
445
446
  fn check_expand(&self, rb_self: Obj<Self>, key_len: usize) -> magnus::error::Result<()> {
446
447
  // CAST: no-op on 32-bit, widening on 64-bit.
447
448
  let used = self.inner(|inner| inner.load_used())? as usize;
448
449
  let entry_len = RawEntry::calc_total_len(key_len)?;
450
+ let required_len = used.add_chk(entry_len)?;
451
+ let mut target_cap = self.capacity();
449
452
 
453
+ let mut needs_resize = false;
450
454
  // We need the mmapped region to contain at least one byte beyond the
451
- // written data to create a NUL- terminated C string. Validate that
452
- // new length does not exactly match or exceed the length of the mmap.
453
- while self.capacity() <= used.add_chk(entry_len)? {
454
- self.expand_to_fit(rb_self, self.capacity().mul_chk(2)?)?;
455
+ // written data to create a NUL-terminated C string. Validate that
456
+ // new length does not exactly match the length of the mmap.
457
+ if target_cap <= required_len {
458
+ needs_resize = true;
459
+ target_cap = required_len + 1;
460
+ }
461
+
462
+ let (current_file_len, original_file_len) =
463
+ self.inner(|inner| Ok((inner.check_file_len()?, inner.file_len())))?;
464
+
465
+ let file_modified = current_file_len != original_file_len;
466
+ if file_modified {
467
+ // Ensure our new capacity is at least as large as the actual file.
468
+ // Erroring out without first resizing the mmap would leave us stuck
469
+ // in a bad state.
470
+ target_cap = current_file_len
471
+ }
472
+
473
+ if needs_resize {
474
+ self.expand_to_fit(rb_self, target_cap)?;
475
+ }
476
+
477
+ if file_modified {
478
+ // Return an error so the caller is alerted that there were concurrent writes to the
479
+ // file.
480
+ let path = self.inner(|inner| Ok(inner.path()))?;
481
+ return Err(MmapError::UnexpectedFileLength {
482
+ path,
483
+ len: current_file_len,
484
+ expected_len: original_file_len,
485
+ }
486
+ .into());
455
487
  }
456
488
 
457
489
  Ok(())
@@ -652,6 +684,7 @@ mod test {
652
684
  use super::*;
653
685
  use crate::raw_entry::RawEntry;
654
686
  use crate::testhelper::TestFile;
687
+ use std::os::unix::prelude::AsRawFd;
655
688
 
656
689
  /// Create a wrapped MmapedFile object.
657
690
  fn create_obj() -> Obj<MmapedFile> {
@@ -881,4 +914,37 @@ mod test {
881
914
  // Validate that we have expanded the mmap, ensuring a trailing NUL.
882
915
  assert!(rs_self.capacity() > current_cap);
883
916
  }
917
+
918
+ #[test]
919
+ fn test_detect_external_resize() {
920
+ let _cleanup = unsafe { magnus::embed::init() };
921
+ let ruby = magnus::Ruby::get().unwrap();
922
+ crate::init(&ruby).unwrap();
923
+
924
+ let TestFile {
925
+ file,
926
+ path,
927
+ dir: _dir,
928
+ } = TestFile::new(&[0u8; 8]);
929
+
930
+ let path_str = path.display().to_string();
931
+ let rpath = RString::new(&path_str);
932
+
933
+ // Object created successfully
934
+ let result: std::result::Result<Obj<MmapedFile>, Error> =
935
+ eval!("FastMmapedFileRs.new(path)", path = rpath);
936
+ assert!(result.is_ok());
937
+ let obj = result.unwrap();
938
+
939
+ let rs_self = &*obj;
940
+
941
+ let file_len = 1 << 32;
942
+ nix::unistd::ftruncate(file.as_raw_fd(), file_len).unwrap();
943
+
944
+ // We error when the file is externally modified.
945
+ assert!(rs_self.check_expand(obj, 512).is_err());
946
+
947
+ // We updated the object to use the new size.
948
+ assert_eq!(rs_self.capacity(), file_len as usize);
949
+ }
884
950
  }
@@ -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', 'true') == '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: true)
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', 'true') == "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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Prometheus
2
2
  module Client
3
- VERSION = '0.28.1'.freeze
3
+ VERSION = '1.0.0'.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.28.1
4
+ version: 1.0.0
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-10-05 00:00:00.000000000 Z
14
+ date: 2023-11-15 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rb_sys
@@ -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
@@ -195,26 +176,6 @@ files:
195
176
  - lib/prometheus/client/support/unicorn.rb
196
177
  - lib/prometheus/client/uses_value_type.rb
197
178
  - lib/prometheus/client/version.rb
198
- - vendor/c/hashmap/.gitignore
199
- - vendor/c/hashmap/LICENSE
200
- - vendor/c/hashmap/README.md
201
- - vendor/c/hashmap/_config.yml
202
- - vendor/c/hashmap/src/hashmap.c
203
- - vendor/c/hashmap/src/hashmap.h
204
- - vendor/c/hashmap/test/Makefile
205
- - vendor/c/hashmap/test/hashmap_test.c
206
- - vendor/c/jsmn/.travis.yml
207
- - vendor/c/jsmn/LICENSE
208
- - vendor/c/jsmn/Makefile
209
- - vendor/c/jsmn/README.md
210
- - vendor/c/jsmn/example/jsondump.c
211
- - vendor/c/jsmn/example/simple.c
212
- - vendor/c/jsmn/jsmn.c
213
- - vendor/c/jsmn/jsmn.h
214
- - vendor/c/jsmn/library.json
215
- - vendor/c/jsmn/test/test.h
216
- - vendor/c/jsmn/test/tests.c
217
- - vendor/c/jsmn/test/testutil.h
218
179
  homepage: https://gitlab.com/gitlab-org/prometheus-client-mmap
219
180
  licenses:
220
181
  - Apache-2.0
@@ -237,6 +198,6 @@ requirements: []
237
198
  rubygems_version: 3.3.26
238
199
  signing_key:
239
200
  specification_version: 4
240
- summary: A suite of instrumentation metric primitivesthat can be exposed through a
241
- web services interface.
201
+ summary: A suite of instrumentation metric primitives that can be exposed through
202
+ a web services interface.
242
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
- }