fix: 拒绝ACT episode编号冲突

This commit is contained in:
2026-08-10 18:26:38 +08:00
parent 6982620041
commit e20c5a983e
2 changed files with 35 additions and 9 deletions
+28 -7
View File
@@ -744,13 +744,7 @@ def _push_recording_frames(recorder, control_ns, frame_number):
)
@requires_h5py
def test_end_to_end_fake_episode_saves_and_returns_idle(tmp_path):
recorder = _recorder_for_test(tmp_path)
recorder._handle_right_b(grip=False)
assert recorder.state is RecordingState.ARMED
def _finish_fake_episode(recorder):
start_ns = recorder._now_ns()
frame_number = 1001
for offset, seq in enumerate(range(100, 107)):
@@ -768,12 +762,39 @@ def test_end_to_end_fake_episode_saves_and_returns_idle(tmp_path):
_push_recording_frames(recorder, final_ns, frame_number)
recorder._on_control_sample(_control_message(108, final_ns, grip=False))
@requires_h5py
def test_end_to_end_fake_episode_saves_and_returns_idle(tmp_path):
recorder = _recorder_for_test(tmp_path)
recorder._handle_right_b(grip=False)
assert recorder.state is RecordingState.ARMED
_finish_fake_episode(recorder)
assert (tmp_path / "tomato_pick" / "episode_0.hdf5").is_file()
assert recorder.state is RecordingState.IDLE
assert "SAVING" in recorder._status_pub.messages
assert recorder._status_pub.messages[-2:] == ["SAVED", "IDLE"]
@requires_h5py
def test_final_publish_rejects_allocated_episode_number_conflict(tmp_path):
recorder = _recorder_for_test(tmp_path)
recorder._handle_right_b(grip=False)
existing = recorder._task_dir / "episode_0.hdf5"
existing.write_bytes(b"existing")
_finish_fake_episode(recorder)
assert existing.read_bytes() == b"existing"
assert not (recorder._task_dir / "episode_1.hdf5").exists()
rejected = list((recorder._task_dir / "rejected").glob("*.hdf5"))
assert len(rejected) == 1
with h5py.File(rejected[0], "r") as root:
assert root.attrs["reject_reason"] == "episode_number_conflict"
@requires_h5py
def test_discard_and_interrupt_only_process_current_partial(tmp_path):
recorder = _recorder_for_test(tmp_path)
@@ -1099,6 +1099,7 @@ class ActEpisodeRecorder(Node):
self._writer: EpisodeWriter | None = None
self._store: EpisodeStore | None = None
self._partial_path: Path | None = None
self._episode_index: int | None = None
self._camera_baselines: tuple[CameraStats, CameraStats] | None = None
self._saving_deadline_ns: int | None = None
@@ -1285,6 +1286,7 @@ class ActEpisodeRecorder(Node):
self._publish_state(RecordingState.IDLE, "disk_write_error")
return
self._store = store
self._episode_index = episode_index
self._writer = EpisodeWriter(
store,
queue_size=self._writer_queue_size,
@@ -1533,6 +1535,7 @@ class ActEpisodeRecorder(Node):
def _complete_save(self) -> None:
assert self._store is not None
assert self._partial_path is not None
assert self._episode_index is not None
partial = self._partial_path
self._store.close()
report = validate_episode(partial, self._quality_limits)
@@ -1546,8 +1549,9 @@ class ActEpisodeRecorder(Node):
root.attrs["interrupted"] = np.bool_(False)
for name, value in report.metrics.items():
root.attrs[name] = value
episode_index = next_episode_index(self._task_dir)
destination = self._task_dir / f"episode_{episode_index}.hdf5"
destination = (
self._task_dir / f"episode_{self._episode_index}.hdf5"
)
try:
publish_without_overwrite(partial, destination)
except FileExistsError:
@@ -1625,6 +1629,7 @@ class ActEpisodeRecorder(Node):
self._writer = None
self._store = None
self._partial_path = None
self._episode_index = None
self._camera_baselines = None
self._saving_deadline_ns = None
self._publish_state(RecordingState.IDLE)