Preserve onboard preview recordings across backpressure and share the complete spatial scene
This commit is contained in:
@@ -78,3 +78,63 @@ def test_reopened_viewer_does_not_replay_cached_points_after_source_pause(monkey
|
||||
finally:
|
||||
bridge.close()
|
||||
sub.thread.join(timeout=3)
|
||||
|
||||
|
||||
def test_slow_consumer_resumes_same_recording_and_replays_unacknowledged_batch():
|
||||
"""A >500ms delivery pause used to retire the recording and lose its route."""
|
||||
bridge = NodeRerunBridge()
|
||||
sub = bridge.subscribe("synthetic-view")
|
||||
try:
|
||||
batch = sub.next_batch()
|
||||
assert batch and batch[1].startswith(b"RRF2")
|
||||
sequence = batch[0]
|
||||
# Produce several tiny frames without draining the bounded outbox.
|
||||
for index in range(1, 8):
|
||||
bridge.process(points(index))
|
||||
time.sleep(0.12)
|
||||
assert not sub.closed.is_set()
|
||||
assert sub.output.qsize() <= 2
|
||||
old_thread = sub.thread
|
||||
sub.release()
|
||||
resumed = bridge.subscribe("synthetic-view", sequence - 1)
|
||||
assert resumed is sub and resumed.thread is old_thread
|
||||
assert resumed.next_batch() == batch # ACK lost: resend the exact RRD.
|
||||
resumed.acknowledge(sequence)
|
||||
following = resumed.next_batch()
|
||||
assert following[0] == sequence + 1
|
||||
resumed.release()
|
||||
again = bridge.subscribe("synthetic-view", following[0])
|
||||
assert again is sub and again.pending is None # Delivered ACK lost at sender.
|
||||
again.release()
|
||||
finally:
|
||||
bridge.close()
|
||||
sub.thread.join(timeout=3)
|
||||
assert not sub.thread.is_alive()
|
||||
|
||||
|
||||
def test_resumption_cannot_silently_replace_expired_recording():
|
||||
import pytest
|
||||
bridge = NodeRerunBridge()
|
||||
try:
|
||||
with pytest.raises(ValueError, match="expired"):
|
||||
bridge.subscribe("missing-view", 2)
|
||||
assert bridge.subscribers == []
|
||||
finally:
|
||||
bridge.close()
|
||||
|
||||
|
||||
def test_closing_view_releases_capacity_without_waiting_for_resume_grace():
|
||||
bridge = NodeRerunBridge()
|
||||
views = []
|
||||
try:
|
||||
for index in range(4):
|
||||
sub = bridge.subscribe(f"view-{index}")
|
||||
views.append(sub)
|
||||
sub.release()
|
||||
bridge.release_view(f"view-{index}")
|
||||
assert sub.closed.is_set()
|
||||
assert bridge.views == {}
|
||||
finally:
|
||||
bridge.close()
|
||||
for sub in views:
|
||||
sub.thread.join(timeout=3)
|
||||
|
||||
Reference in New Issue
Block a user