Skip to content

Commit 181b57e

Browse files
rmcdanielclaude
andcommitted
Meter v1 projection history bytes in Core's canonical unit
Server #812 (#770) makes PHP's Waterline v1 projection count history bytes as Core's HistoryBudget::sizeOfEvent does: the event type's bytes plus its payload encoded with JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE, the unit DW_V2_LIMIT_HISTORY_TRANSACTION_BYTES limits everywhere else. Native, like published PHP through 2.11.5, counted each whole event's JSON with its id, sequence and time and escaped Unicode. Native now uses the canonical unit for the byte limit and for the stored summary's history_size_bytes. #812's LegacyV1Projection::normalize, run on the published 2.11.5 image's Core, counts the bare test source's two events as 1280 and 402 bytes (1682 in all, where the old unit gave 1870); native matches. Hold until the shared fixture reference moves to a Server release carrying #812: the waterline-import fixture records history_size_bytes from the published reference. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent d841887 commit 181b57e

1 file changed

Lines changed: 18 additions & 17 deletions

File tree

‎rust/src/runtime/waterline_import.rs‎

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -609,14 +609,7 @@ fn events(source: &PhpArray, logs: &[PhpArray], signals: &[PhpArray], exceptions
609609
recorded_at,
610610
payload,
611611
};
612-
let size = object(vec![
613-
("event_type", text(event.event_type)),
614-
("recorded_at", optional(json_time(event.recorded_at))),
615-
("payload", event.payload.clone()),
616-
("sequence", Php::Int(event.sequence)),
617-
("id", text(&event.id)),
618-
]).encode(Flags { unescaped_slashes: true, ..Flags::default() }).len();
619-
bytes = bytes.checked_add(size).unwrap_or(usize::MAX);
612+
bytes = bytes.checked_add(event_bytes(&event)).unwrap_or(usize::MAX);
620613
if let Some(error) = exceeded(limits, 0, bytes) {
621614
return Err((error, index + 1));
622615
}
@@ -625,6 +618,15 @@ fn events(source: &PhpArray, logs: &[PhpArray], signals: &[PhpArray], exceptions
625618
Ok((built, bytes))
626619
}
627620

621+
/// Core's history-transaction byte unit, `HistoryBudget::sizeOfEvent`: the
622+
/// event type's bytes plus its payload as `json_encode` with
623+
/// `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE` writes it (Server #770).
624+
/// The event's id, sequence and time are not counted.
625+
fn event_bytes(event: &Event) -> usize {
626+
event.event_type.len()
627+
+ event.payload.encode(Flags { unescaped_slashes: true, unescaped_unicode: true, ..Flags::default() }).len()
628+
}
629+
628630
/// `report`: the projection report, with the first error's reason, message
629631
/// and remediation at the top of a rejection, then `extra`.
630632
fn report(outcome: &Outcome, status: &str, extra: Vec<(&str, Value)>) -> Value {
@@ -1352,13 +1354,7 @@ mod tests {
13521354
let (outcome, start) = events_built(|| normalize_bounded("src-1", source, None, &limited(None, None)));
13531355
let Outcome::Valid(all) = outcome else { panic!("valid") };
13541356
assert_eq!(start, all.events.len());
1355-
let first = |count: usize| all.events[..count].iter().map(|event| object(vec![
1356-
("event_type", text(event.event_type)),
1357-
("recorded_at", optional(json_time(event.recorded_at))),
1358-
("payload", event.payload.clone()),
1359-
("sequence", Php::Int(event.sequence)),
1360-
("id", text(&event.id)),
1361-
]).encode(Flags { unescaped_slashes: true, ..Flags::default() }).len()).sum::<usize>();
1357+
let first = |count: usize| all.events[..count].iter().map(event_bytes).sum::<usize>();
13621358
let (outcome, built) = events_built(|| normalize_bounded("src-1", source, None, &limited(None, Some(first(4)))));
13631359
assert!(matches!(outcome, Outcome::TooLarge { built: 5, .. }));
13641360
assert_eq!(built, 5);
@@ -1367,7 +1363,8 @@ mod tests {
13671363
#[test]
13681364
fn events_and_history_size_follow_php() {
13691365
// PHP 2.11.1: LegacyV1Projection::normalize('src-1', bare source, 'ns-1')
1370-
// printed these event encodings (json_encode, JSON_UNESCAPED_SLASHES).
1366+
// printed these event encodings (json_encode, JSON_UNESCAPED_SLASHES),
1367+
// which fix the events' ids and payloads.
13711368
let source = super::super::php_value::decode(br#"{"operator_id":"v1:4501","engine_source":"v1","class":"App\\Workflows\\Legacy\\Bare","status":"completed"}"#)
13721369
.unwrap();
13731370
let Outcome::Valid(normalized) = normalize("src-1", source.array().unwrap(), Some("ns-1")) else { panic!("valid") };
@@ -1380,7 +1377,11 @@ mod tests {
13801377
]).encode(Flags { unescaped_slashes: true, ..Flags::default() })).collect();
13811378
assert_eq!(encoded[0].len(), 1374, "{}", encoded[0]);
13821379
assert_eq!(encoded[1].len(), 496, "{}", encoded[1]);
1383-
assert_eq!(normalized.history_size_bytes, 1870);
1380+
// Server #812's LegacyV1Projection::normalize on Core 2.15's
1381+
// HistoryBudget::sizeOfEvent counted 1280 and 402 bytes for these
1382+
// events: their types and payloads, not their ids, sequences or times.
1383+
assert_eq!(normalized.events.iter().map(event_bytes).collect::<Vec<_>>(), [1280, 402]);
1384+
assert_eq!(normalized.history_size_bytes, 1682);
13841385
assert_eq!(normalized.workflow_id, "v1:src-1:c8c25815a3332910ba072598");
13851386
assert_eq!(normalized.run_id, "b0ee56b2b89080ea9181490e2f");
13861387
assert_eq!(normalized.events[0].id, "9730c0bb4149e0a120cc8a8d7e");

0 commit comments

Comments
 (0)