prometheus-client-mmap 0.15.0 → 0.16.0
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/ext/fast_mmaped_file/hashmap.c +410 -467
- data/ext/fast_mmaped_file/jsmn.c +259 -244
- data/ext/fast_mmaped_file/mmap.c +3 -0
- data/lib/fast_mmaped_file.bundle +0 -0
- data/lib/prometheus/client/helper/file_locker.rb +5 -1
- data/lib/prometheus/client/helper/mmaped_file.rb +1 -0
- data/lib/prometheus/client/version.rb +1 -1
- data/lib/prometheus/client.rb +4 -0
- metadata +3 -3
data/ext/fast_mmaped_file/jsmn.c
CHANGED
@@ -3,303 +3,319 @@
|
|
3
3
|
/**
|
4
4
|
* Allocates a fresh unused token from the token pull.
|
5
5
|
*/
|
6
|
-
static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
tok->size = 0;
|
6
|
+
static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens, size_t num_tokens) {
|
7
|
+
jsmntok_t *tok;
|
8
|
+
if (parser->toknext >= num_tokens) {
|
9
|
+
return NULL;
|
10
|
+
}
|
11
|
+
tok = &tokens[parser->toknext++];
|
12
|
+
tok->start = tok->end = -1;
|
13
|
+
tok->size = 0;
|
15
14
|
#ifdef JSMN_PARENT_LINKS
|
16
|
-
|
15
|
+
tok->parent = -1;
|
17
16
|
#endif
|
18
|
-
|
17
|
+
return tok;
|
19
18
|
}
|
20
19
|
|
21
20
|
/**
|
22
21
|
* Fills token type and boundaries.
|
23
22
|
*/
|
24
|
-
static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
token->size = 0;
|
23
|
+
static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, int start, int end) {
|
24
|
+
token->type = type;
|
25
|
+
token->start = start;
|
26
|
+
token->end = end;
|
27
|
+
token->size = 0;
|
30
28
|
}
|
31
29
|
|
32
30
|
/**
|
33
31
|
* Fills next available token with JSON primitive.
|
34
32
|
*/
|
35
|
-
static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
|
36
|
-
|
37
|
-
|
38
|
-
int start;
|
33
|
+
static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, size_t num_tokens) {
|
34
|
+
jsmntok_t *token;
|
35
|
+
int start;
|
39
36
|
|
40
|
-
|
37
|
+
start = parser->pos;
|
41
38
|
|
42
|
-
|
43
|
-
|
39
|
+
for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
|
40
|
+
switch (js[parser->pos]) {
|
44
41
|
#ifndef JSMN_STRICT
|
45
|
-
|
46
|
-
|
42
|
+
/* In strict mode primitive must be followed by "," or "}" or "]" */
|
43
|
+
case ':':
|
47
44
|
#endif
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
case '\t':
|
46
|
+
case '\r':
|
47
|
+
case '\n':
|
48
|
+
case ' ':
|
49
|
+
case ',':
|
50
|
+
case ']':
|
51
|
+
case '}':
|
52
|
+
goto found;
|
53
|
+
}
|
54
|
+
if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
|
55
|
+
parser->pos = start;
|
56
|
+
return JSMN_ERROR_INVAL;
|
57
|
+
}
|
58
|
+
}
|
57
59
|
#ifdef JSMN_STRICT
|
58
|
-
|
59
|
-
|
60
|
-
|
60
|
+
/* In strict mode primitive must be followed by a comma/object/array */
|
61
|
+
parser->pos = start;
|
62
|
+
return JSMN_ERROR_PART;
|
61
63
|
#endif
|
62
64
|
|
63
65
|
found:
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
66
|
+
if (tokens == NULL) {
|
67
|
+
parser->pos--;
|
68
|
+
return 0;
|
69
|
+
}
|
70
|
+
token = jsmn_alloc_token(parser, tokens, num_tokens);
|
71
|
+
if (token == NULL) {
|
72
|
+
parser->pos = start;
|
73
|
+
return JSMN_ERROR_NOMEM;
|
74
|
+
}
|
75
|
+
jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
|
74
76
|
#ifdef JSMN_PARENT_LINKS
|
75
|
-
|
77
|
+
token->parent = parser->toksuper;
|
76
78
|
#endif
|
77
|
-
|
78
|
-
|
79
|
+
parser->pos--;
|
80
|
+
return 0;
|
79
81
|
}
|
80
82
|
|
81
83
|
/**
|
82
84
|
* Fills next token with JSON string.
|
83
85
|
*/
|
84
|
-
static int jsmn_parse_string(jsmn_parser *parser, const char *js,
|
85
|
-
|
86
|
-
jsmntok_t *token;
|
86
|
+
static int jsmn_parse_string(jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, size_t num_tokens) {
|
87
|
+
jsmntok_t *token;
|
87
88
|
|
88
|
-
|
89
|
+
int start = parser->pos;
|
89
90
|
|
90
|
-
|
91
|
+
parser->pos++;
|
91
92
|
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
/* Skip starting quote */
|
94
|
+
for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
|
95
|
+
char c = js[parser->pos];
|
95
96
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
97
|
+
/* Quote: end of string */
|
98
|
+
if (c == '\"') {
|
99
|
+
if (tokens == NULL) {
|
100
|
+
return 0;
|
101
|
+
}
|
102
|
+
token = jsmn_alloc_token(parser, tokens, num_tokens);
|
103
|
+
if (token == NULL) {
|
104
|
+
parser->pos = start;
|
105
|
+
return JSMN_ERROR_NOMEM;
|
106
|
+
}
|
107
|
+
jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos);
|
107
108
|
#ifdef JSMN_PARENT_LINKS
|
108
|
-
|
109
|
+
token->parent = parser->toksuper;
|
109
110
|
#endif
|
110
|
-
|
111
|
-
|
111
|
+
return 0;
|
112
|
+
}
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
114
|
+
/* Backslash: Quoted symbol expected */
|
115
|
+
if (c == '\\' && parser->pos + 1 < len) {
|
116
|
+
int i;
|
117
|
+
parser->pos++;
|
118
|
+
switch (js[parser->pos]) {
|
119
|
+
/* Allowed escaped symbols */
|
120
|
+
case '\"':
|
121
|
+
case '/':
|
122
|
+
case '\\':
|
123
|
+
case 'b':
|
124
|
+
case 'f':
|
125
|
+
case 'r':
|
126
|
+
case 'n':
|
127
|
+
case 't':
|
128
|
+
break;
|
129
|
+
/* Allows escaped symbol \uXXXX */
|
130
|
+
case 'u':
|
131
|
+
parser->pos++;
|
132
|
+
for (i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
|
133
|
+
/* If it isn't a hex character we have an error */
|
134
|
+
if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
|
135
|
+
(js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
|
136
|
+
(js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
|
137
|
+
parser->pos = start;
|
138
|
+
return JSMN_ERROR_INVAL;
|
139
|
+
}
|
140
|
+
parser->pos++;
|
141
|
+
}
|
142
|
+
parser->pos--;
|
143
|
+
break;
|
144
|
+
/* Unexpected symbol */
|
145
|
+
default:
|
146
|
+
parser->pos = start;
|
147
|
+
return JSMN_ERROR_INVAL;
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
parser->pos = start;
|
152
|
+
return JSMN_ERROR_PART;
|
146
153
|
}
|
147
154
|
|
148
155
|
/**
|
149
156
|
* Parse JSON string and fill tokens.
|
150
157
|
*/
|
151
|
-
int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
int count = parser->toknext;
|
158
|
+
int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, unsigned int num_tokens) {
|
159
|
+
int r;
|
160
|
+
int i;
|
161
|
+
jsmntok_t *token;
|
162
|
+
int count = parser->toknext;
|
157
163
|
|
158
|
-
|
159
|
-
|
160
|
-
|
164
|
+
for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
|
165
|
+
char c;
|
166
|
+
jsmntype_t type;
|
161
167
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
168
|
+
c = js[parser->pos];
|
169
|
+
switch (c) {
|
170
|
+
case '{':
|
171
|
+
case '[':
|
172
|
+
count++;
|
173
|
+
if (tokens == NULL) {
|
174
|
+
break;
|
175
|
+
}
|
176
|
+
token = jsmn_alloc_token(parser, tokens, num_tokens);
|
177
|
+
if (token == NULL) return JSMN_ERROR_NOMEM;
|
178
|
+
if (parser->toksuper != -1) {
|
179
|
+
tokens[parser->toksuper].size++;
|
174
180
|
#ifdef JSMN_PARENT_LINKS
|
175
|
-
|
181
|
+
token->parent = parser->toksuper;
|
176
182
|
#endif
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
183
|
+
}
|
184
|
+
token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
|
185
|
+
token->start = parser->pos;
|
186
|
+
parser->toksuper = parser->toknext - 1;
|
187
|
+
break;
|
188
|
+
case '}':
|
189
|
+
case ']':
|
190
|
+
if (tokens == NULL) break;
|
191
|
+
type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
|
186
192
|
#ifdef JSMN_PARENT_LINKS
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
193
|
+
if (parser->toknext < 1) {
|
194
|
+
return JSMN_ERROR_INVAL;
|
195
|
+
}
|
196
|
+
token = &tokens[parser->toknext - 1];
|
197
|
+
for (;;) {
|
198
|
+
if (token->start != -1 && token->end == -1) {
|
199
|
+
if (token->type != type) {
|
200
|
+
return JSMN_ERROR_INVAL;
|
201
|
+
}
|
202
|
+
token->end = parser->pos + 1;
|
203
|
+
parser->toksuper = token->parent;
|
204
|
+
break;
|
205
|
+
}
|
206
|
+
if (token->parent == -1) {
|
207
|
+
if (token->type != type || parser->toksuper == -1) {
|
208
|
+
return JSMN_ERROR_INVAL;
|
209
|
+
}
|
210
|
+
break;
|
211
|
+
}
|
212
|
+
token = &tokens[token->parent];
|
213
|
+
}
|
208
214
|
#else
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
215
|
+
for (i = parser->toknext - 1; i >= 0; i--) {
|
216
|
+
token = &tokens[i];
|
217
|
+
if (token->start != -1 && token->end == -1) {
|
218
|
+
if (token->type != type) {
|
219
|
+
return JSMN_ERROR_INVAL;
|
220
|
+
}
|
221
|
+
parser->toksuper = -1;
|
222
|
+
token->end = parser->pos + 1;
|
223
|
+
break;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
/* Error if unmatched closing bracket */
|
227
|
+
if (i == -1) return JSMN_ERROR_INVAL;
|
228
|
+
for (; i >= 0; i--) {
|
229
|
+
token = &tokens[i];
|
230
|
+
if (token->start != -1 && token->end == -1) {
|
231
|
+
parser->toksuper = i;
|
232
|
+
break;
|
233
|
+
}
|
234
|
+
}
|
229
235
|
#endif
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
236
|
+
break;
|
237
|
+
case '\"':
|
238
|
+
r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
|
239
|
+
if (r < 0) return r;
|
240
|
+
count++;
|
241
|
+
if (parser->toksuper != -1 && tokens != NULL) tokens[parser->toksuper].size++;
|
242
|
+
break;
|
243
|
+
case '\t':
|
244
|
+
case '\r':
|
245
|
+
case '\n':
|
246
|
+
case ' ':
|
247
|
+
break;
|
248
|
+
case ':':
|
249
|
+
parser->toksuper = parser->toknext - 1;
|
250
|
+
break;
|
251
|
+
case ',':
|
252
|
+
if (tokens != NULL && parser->toksuper != -1 && tokens[parser->toksuper].type != JSMN_ARRAY &&
|
253
|
+
tokens[parser->toksuper].type != JSMN_OBJECT) {
|
247
254
|
#ifdef JSMN_PARENT_LINKS
|
248
|
-
|
255
|
+
parser->toksuper = tokens[parser->toksuper].parent;
|
249
256
|
#else
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
257
|
+
for (i = parser->toknext - 1; i >= 0; i--) {
|
258
|
+
if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
|
259
|
+
if (tokens[i].start != -1 && tokens[i].end == -1) {
|
260
|
+
parser->toksuper = i;
|
261
|
+
break;
|
262
|
+
}
|
263
|
+
}
|
264
|
+
}
|
258
265
|
#endif
|
259
|
-
|
260
|
-
|
266
|
+
}
|
267
|
+
break;
|
261
268
|
#ifdef JSMN_STRICT
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
269
|
+
/* In strict mode primitives are: numbers and booleans */
|
270
|
+
case '-':
|
271
|
+
case '0':
|
272
|
+
case '1':
|
273
|
+
case '2':
|
274
|
+
case '3':
|
275
|
+
case '4':
|
276
|
+
case '5':
|
277
|
+
case '6':
|
278
|
+
case '7':
|
279
|
+
case '8':
|
280
|
+
case '9':
|
281
|
+
case 't':
|
282
|
+
case 'f':
|
283
|
+
case 'n':
|
284
|
+
/* And they must not be keys of the object */
|
285
|
+
if (tokens != NULL && parser->toksuper != -1) {
|
286
|
+
jsmntok_t *t = &tokens[parser->toksuper];
|
287
|
+
if (t->type == JSMN_OBJECT || (t->type == JSMN_STRING && t->size != 0)) {
|
288
|
+
return JSMN_ERROR_INVAL;
|
289
|
+
}
|
290
|
+
}
|
274
291
|
#else
|
275
|
-
|
276
|
-
|
292
|
+
/* In non-strict mode every unquoted value is a primitive */
|
293
|
+
default:
|
277
294
|
#endif
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
break;
|
295
|
+
r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
|
296
|
+
if (r < 0) return r;
|
297
|
+
count++;
|
298
|
+
if (parser->toksuper != -1 && tokens != NULL) tokens[parser->toksuper].size++;
|
299
|
+
break;
|
284
300
|
|
285
301
|
#ifdef JSMN_STRICT
|
286
|
-
|
287
|
-
|
288
|
-
|
302
|
+
/* Unexpected char in strict mode */
|
303
|
+
default:
|
304
|
+
return JSMN_ERROR_INVAL;
|
289
305
|
#endif
|
290
|
-
|
291
|
-
|
306
|
+
}
|
307
|
+
}
|
292
308
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
309
|
+
if (tokens != NULL) {
|
310
|
+
for (i = parser->toknext - 1; i >= 0; i--) {
|
311
|
+
/* Unmatched opened object or array */
|
312
|
+
if (tokens[i].start != -1 && tokens[i].end == -1) {
|
313
|
+
return JSMN_ERROR_PART;
|
314
|
+
}
|
315
|
+
}
|
316
|
+
}
|
301
317
|
|
302
|
-
|
318
|
+
return count;
|
303
319
|
}
|
304
320
|
|
305
321
|
/**
|
@@ -307,8 +323,7 @@ int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
|
|
307
323
|
* available.
|
308
324
|
*/
|
309
325
|
void jsmn_init(jsmn_parser *parser) {
|
310
|
-
|
311
|
-
|
312
|
-
|
326
|
+
parser->pos = 0;
|
327
|
+
parser->toknext = 0;
|
328
|
+
parser->toksuper = -1;
|
313
329
|
}
|
314
|
-
|
data/ext/fast_mmaped_file/mmap.c
CHANGED
data/lib/fast_mmaped_file.bundle
CHANGED
Binary file
|
@@ -25,7 +25,10 @@ module Prometheus
|
|
25
25
|
@file_locks ||= {}
|
26
26
|
return false unless @file_locks[filepath]
|
27
27
|
|
28
|
-
@file_locks
|
28
|
+
file = @file_locks[filepath]
|
29
|
+
file.flock(File::LOCK_UN)
|
30
|
+
file.close
|
31
|
+
@file_locks.delete(filepath)
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
@@ -34,6 +37,7 @@ module Prometheus
|
|
34
37
|
@file_locks ||= {}
|
35
38
|
@file_locks.values.each do |file|
|
36
39
|
file.flock(File::LOCK_UN)
|
40
|
+
file.close
|
37
41
|
end
|
38
42
|
|
39
43
|
@file_locks = {}
|
data/lib/prometheus/client.rb
CHANGED
@@ -37,6 +37,10 @@ module Prometheus
|
|
37
37
|
::Prometheus::Client::MmapedValue.reset_and_reinitialize
|
38
38
|
end
|
39
39
|
|
40
|
+
def cleanup!
|
41
|
+
Dir.glob("#{configuration.multiprocess_files_dir}/*.db").each { |f| File.unlink(f) if File.exist?(f) }
|
42
|
+
end
|
43
|
+
|
40
44
|
# With `force: false`: reinitializes metric files only for processes with the changed PID.
|
41
45
|
# With `force: true`: reinitializes all metrics files.
|
42
46
|
# Always keeps the registry.
|
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.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Schmidt
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-03-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fuzzbert
|
@@ -181,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
181
|
- !ruby/object:Gem::Version
|
182
182
|
version: '0'
|
183
183
|
requirements: []
|
184
|
-
rubygems_version: 3.1.
|
184
|
+
rubygems_version: 3.1.6
|
185
185
|
signing_key:
|
186
186
|
specification_version: 4
|
187
187
|
summary: A suite of instrumentation metric primitivesthat can be exposed through a
|