Skip to content

Commit 4d8a191

Browse files
committed
Add total item size
1 parent a10872c commit 4d8a191

File tree

1 file changed

+98
-13
lines changed

1 file changed

+98
-13
lines changed

relay-event-normalization/src/eap/trimming.rs

Lines changed: 98 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct SizeState {
2626
/// This means that large attributes will be trimmed or discarded before small ones.
2727
#[derive(Default)]
2828
pub struct TrimmingProcessor {
29+
max_item_size: Option<usize>,
2930
size_state: Vec<SizeState>,
3031
/// Whether we are currently trimming a collection of attributes.
3132
/// This case needs to be distinguished for the purpose of accounting
@@ -35,8 +36,24 @@ pub struct TrimmingProcessor {
3536

3637
impl TrimmingProcessor {
3738
/// Creates a new trimming processor.
38-
pub fn new() -> Self {
39-
Self::default()
39+
///
40+
/// The `max_item_size` parameter is a global byte size
41+
/// limit for the item being processed.
42+
pub fn new(max_item_size: Option<usize>) -> Self {
43+
let mut size_state = Vec::new();
44+
if max_item_size.is_some() {
45+
size_state.push(SizeState {
46+
size_remaining: max_item_size,
47+
encountered_at_depth: 0,
48+
max_depth: None,
49+
});
50+
}
51+
52+
Self {
53+
max_item_size,
54+
size_state,
55+
in_attributes: false,
56+
}
4057
}
4158

4259
fn should_remove_container<T: Empty>(&self, value: &T, state: &ProcessingState<'_>) -> bool {
@@ -139,9 +156,7 @@ impl Processor for TrimmingProcessor {
139156
return Ok(());
140157
}
141158

142-
if let Some(size_state) = self.size_state.last()
143-
&& let Some(size_remaining) = size_state.size_remaining
144-
{
159+
if let Some(size_remaining) = self.remaining_size() {
145160
crate::trimming::trim_string(value, meta, size_remaining, 0);
146161
}
147162

@@ -307,10 +322,12 @@ mod tests {
307322

308323
#[derive(Debug, Clone, Empty, IntoValue, FromValue, ProcessValue)]
309324
struct TestObject {
310-
#[metastructure(max_bytes = 40, trim = true)]
311-
attributes: Annotated<Attributes>,
312325
#[metastructure(max_chars = 10, trim = true)]
313326
body: Annotated<String>,
327+
// This should neither be trimmed nor factor into size calculations.
328+
number: Annotated<u64>,
329+
#[metastructure(max_bytes = 40, trim = true)]
330+
attributes: Annotated<Attributes>,
314331
}
315332

316333
#[test]
@@ -323,16 +340,19 @@ mod tests {
323340

324341
let mut value = Annotated::new(TestObject {
325342
attributes: Annotated::new(attributes),
343+
number: Annotated::new(0),
326344
body: Annotated::new("This is longer than allowed".to_owned()),
327345
});
328346

329-
let mut processor = TrimmingProcessor::new();
347+
let mut processor = TrimmingProcessor::new(None);
330348

331349
let state = ProcessingState::new_root(Default::default(), []);
332350
processor::process_value(&mut value, &mut processor, &state).unwrap();
333351

334352
insta::assert_json_snapshot!(SerializableAnnotated(&value), @r###"
335353
{
354+
"body": "This is...",
355+
"number": 0,
336356
"attributes": {
337357
"medium string": {
338358
"type": "string",
@@ -343,7 +363,6 @@ mod tests {
343363
"value": 17
344364
}
345365
},
346-
"body": "This is...",
347366
"_meta": {
348367
"attributes": {
349368
"": {
@@ -394,16 +413,19 @@ mod tests {
394413

395414
let mut value = Annotated::new(TestObject {
396415
attributes: Annotated::new(attributes),
416+
number: Annotated::new(0),
397417
body: Annotated::new("This is longer than allowed".to_owned()),
398418
});
399419

400-
let mut processor = TrimmingProcessor::new();
420+
let mut processor = TrimmingProcessor::new(None);
401421

402422
let state = ProcessingState::new_root(Default::default(), []);
403423
processor::process_value(&mut value, &mut processor, &state).unwrap();
404424

405425
insta::assert_json_snapshot!(SerializableAnnotated(&value), @r###"
406426
{
427+
"body": "This is...",
428+
"number": 0,
407429
"attributes": {
408430
"medium attribute": {
409431
"type": "string",
@@ -414,7 +436,6 @@ mod tests {
414436
"value": 17
415437
}
416438
},
417-
"body": "This is...",
418439
"_meta": {
419440
"attributes": {
420441
"": {
@@ -466,16 +487,19 @@ mod tests {
466487

467488
let mut value = Annotated::new(TestObject {
468489
attributes: Annotated::new(attributes),
490+
number: Annotated::new(0),
469491
body: Annotated::new("This is longer than allowed".to_owned()),
470492
});
471493

472-
let mut processor = TrimmingProcessor::new();
494+
let mut processor = TrimmingProcessor::new(None);
473495

474496
let state = ProcessingState::new_root(Default::default(), []);
475497
processor::process_value(&mut value, &mut processor, &state).unwrap();
476498

477499
insta::assert_json_snapshot!(SerializableAnnotated(&value), @r###"
478500
{
501+
"body": "This is...",
502+
"number": 0,
479503
"attributes": {
480504
"attribute with long name": {
481505
"type": "integer",
@@ -486,7 +510,6 @@ mod tests {
486510
"value": "abcdefgh"
487511
}
488512
},
489-
"body": "This is...",
490513
"_meta": {
491514
"attributes": {
492515
"": {
@@ -510,4 +533,66 @@ mod tests {
510533
}
511534
"###);
512535
}
536+
537+
#[test]
538+
fn test_max_item_size() {
539+
let mut attributes = Attributes::new();
540+
541+
attributes.insert("small", 17); // 13B
542+
attributes.insert("medium string", "This string should be trimmed"); // 42B
543+
attributes.insert("attribute is very large and should be removed", true); // 47B
544+
545+
let mut value = Annotated::new(TestObject {
546+
attributes: Annotated::new(attributes),
547+
number: Annotated::new(0),
548+
body: Annotated::new("Short".to_owned()),
549+
});
550+
551+
// The `body` takes up 5B, the `"small"` attribute 13B, and the key "medium string" another 13B.
552+
// That leaves 9B for the string's value.
553+
// Note that the `number` field doesn't take up any size.
554+
let mut processor = TrimmingProcessor::new(Some(40));
555+
556+
let state = ProcessingState::new_root(Default::default(), []);
557+
processor::process_value(&mut value, &mut processor, &state).unwrap();
558+
559+
insta::assert_json_snapshot!(SerializableAnnotated(&value), @r###"
560+
{
561+
"body": "Short",
562+
"number": 0,
563+
"attributes": {
564+
"medium string": {
565+
"type": "string",
566+
"value": "This s..."
567+
},
568+
"small": {
569+
"type": "integer",
570+
"value": 17
571+
}
572+
},
573+
"_meta": {
574+
"attributes": {
575+
"": {
576+
"len": 101
577+
},
578+
"medium string": {
579+
"value": {
580+
"": {
581+
"rem": [
582+
[
583+
"!limit",
584+
"s",
585+
6,
586+
9
587+
]
588+
],
589+
"len": 29
590+
}
591+
}
592+
}
593+
}
594+
}
595+
}
596+
"###);
597+
}
513598
}

0 commit comments

Comments
 (0)