Skip to content

Commit 442fc17

Browse files
fixup! Store Tachyon samples in bounded columnar blocks
Update the replay progress bar every 1,000 decoded samples instead of only once per block. This matches the previous behavior and prevents the bar from appearing stuck while large blocks are replayed. Clarify in NEWS that Python 3.16 cannot read profiles written in the previous binary format.
1 parent 8865260 commit 442fc17

3 files changed

Lines changed: 18 additions & 26 deletions

File tree

‎Lib/test/test_profiling/test_sampling_profiler/test_binary_format.py‎

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,26 +1175,20 @@ def test_replay_byte_swapped_file(self):
11751175
self.assertEqual(reader.replay_samples(collector), 6)
11761176
self.assert_samples_equal(samples, collector)
11771177

1178-
def test_progress_follows_collected_samples(self):
1179-
"""Progress never counts samples the collector has not received."""
1178+
def test_progress_updates_across_blocks(self):
1179+
"""Progress is reported at fixed intervals across block boundaries."""
11801180
samples, filename = self._write_block_spanning_file()
1181-
1182-
class CountingCollector:
1183-
received = 0
1184-
1185-
def collect(self, stack_frames, timestamps_us):
1186-
self.received += len(timestamps_us)
1187-
1188-
collector = CountingCollector()
11891181
calls = []
11901182
with BinaryReader(filename) as reader:
11911183
reader.replay_samples(
1192-
collector,
1193-
lambda current, total: calls.append(
1194-
(current, collector.received)))
1195-
self.assertGreater(len(calls), 2)
1196-
for current, received in calls:
1197-
self.assertEqual(current, received)
1184+
RawCollector(),
1185+
lambda current, total: calls.append((current, total)))
1186+
total = len(samples)
1187+
self.assertEqual(
1188+
calls,
1189+
[(0, total), (1000, total), (2000, total), (3000, total),
1190+
(4000, total), (total, total)],
1191+
)
11981192

11991193
def test_reader_replays_twice(self):
12001194
"""Replaying twice gives the same samples and statistics."""
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
The :mod:`profiling.sampling` binary output format now stores samples in
2-
independent blocks.
2+
independent blocks. This is a breaking format change: Python 3.16 does not
3+
support reading profiles written in the previous format.

‎Modules/_remote_debugging/binary_io_reader.c‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,6 @@ replay_block(BinaryReader *reader, RemoteDebuggingState *state,
14981498
reader->sample_count - (uint64_t)*replayed) {
14991499
return block_error("more samples than the file header declares");
15001500
}
1501-
Py_ssize_t first_sample = *replayed;
15021501
int result = 0;
15031502
for (uint32_t sample = 0; sample < block->header.sample_count; sample++) {
15041503
if (replay_sample(reader, state, collector, block, sample) < 0) {
@@ -1507,6 +1506,12 @@ replay_block(BinaryReader *reader, RemoteDebuggingState *state,
15071506
}
15081507
(*replayed)++;
15091508
reader->stats.total_samples++;
1509+
if (*replayed % PROGRESS_CALLBACK_INTERVAL == 0 &&
1510+
invoke_progress_callback(progress_callback, *replayed,
1511+
reader->sample_count) < 0) {
1512+
result = -1;
1513+
break;
1514+
}
15101515
}
15111516
if (result == 0) {
15121517
result = validate_block_consumed(reader, block);
@@ -1522,14 +1527,6 @@ replay_block(BinaryReader *reader, RemoteDebuggingState *state,
15221527
Py_CLEAR(stream->batch);
15231528
}
15241529

1525-
/* Report progress once the block's samples reached the collector. */
1526-
if (result == 0 &&
1527-
*replayed / PROGRESS_CALLBACK_INTERVAL !=
1528-
first_sample / PROGRESS_CALLBACK_INTERVAL &&
1529-
invoke_progress_callback(progress_callback, *replayed,
1530-
reader->sample_count) < 0) {
1531-
result = -1;
1532-
}
15331530
return result;
15341531
}
15351532

0 commit comments

Comments
 (0)