-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Description
When running a benchmark with streaming JSON or CSV output enabled, the timestamp_ns field for all MessageLatencyRecord entries is incorrect. The timestamps are all generated at the very end of the test run, causing them to have nearly identical values. This makes it impossible to analyze the test's progress over time, as the difference between the first and last timestamp in the file is a fraction of a second, even for tests that run for several minutes.
Steps to Reproduce
- Run a benchmark with streaming output enabled. For example:
cargo run --release -- -m pmq -s 128 -i 100000 --streaming-output-json /tmp/pmq_test.json
- Examine the output file
/tmp/pmq_test.json. - Observe the
timestamp_nsvalues in thedataarray.
Expected Behavior
The timestamp_ns for each message record should reflect the approximate time that the message was sent. The difference between the first and last timestamp in the file should be close to the total duration of the benchmark run.
Actual Behavior
All timestamp_ns values have the same seconds component, making it appear as though the entire test completed in under a second.
- Example first timestamp:
1765229013390343 - Example last timestamp:
1765229013780759 - Difference:
390,416ns (approx. 0.0004 seconds)
Analysis of Root Cause
The issue lies in how and when the timestamps for the streaming records are generated.
- The benchmark loops in
src/benchmark.rs(e.g.,run_single_threaded_one_way) correctly createMessageobjects, which have a timestamp generated at the moment of creation. - However, during the test loop, only the latency
Durationis collected into aVec. The original message's timestamp is discarded. - After the benchmark loop completes, the code iterates over the collected
Vec<Duration>and creates aMessageLatencyRecordfor each one. - The
MessageLatencyRecord::new()function insrc/results.rsgenerates a new timestamp usingSystemTime::now()at the moment it is called.
Because this happens in a tight loop after the test is finished, all records get a timestamp from that final moment, not from when the original message was sent.
Proposed Solution
The Message struct already contains the correct timestamp. This timestamp needs to be preserved and passed through to the MessageLatencyRecord.
-
Modify
src/results.rs:- Update the
MessageLatencyRecord::newandnew_combinedfunctions to accept atimestamp_ns: u64parameter instead of generating a new one internally.
- Update the
-
Modify
src/benchmark.rs:- In the benchmark loops (e.g.,
run_single_threaded_one_way), the client logic should collect a tuple of(u64, Duration)representing(message_timestamp, latency)instead of just theDuration. - When creating the
MessageLatencyRecordafter the loop, pass the captured timestamp from the tuple into the updatedMessageLatencyRecord::newfunction.
- In the benchmark loops (e.g.,
This will ensure that the timestamps in the streaming output accurately reflect the time each message was sent during the benchmark.