Skip to content

Commit b9f2d2a

Browse files
committed
Fix recording shutdown for node docker
Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com>
1 parent 421be4d commit b9f2d2a

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ test_node_relay: hub node_base standalone_firefox
11251125

11261126
test_standalone_docker: standalone_docker
11271127
DOCKER_COMPOSE_FILE=docker-compose-v3-test-standalone-docker.yaml CONFIG_FILE=standalone_docker_config.toml HUB_CHECKS_INTERVAL=45 TEST_CUSTOM_SPECIFIC_NAME=true \
1128-
RECORD_STANDALONE=true GRID_URL=http://0.0.0.0:4444 LIST_OF_TESTS_AMD64="DeploymentAutoscaling" TEST_PARALLEL_HARDENING=true TEST_DELAY_AFTER_TEST=0 \
1128+
RECORD_STANDALONE=true GRID_URL=http://0.0.0.0:4444 LIST_OF_TESTS_AMD64="DeploymentAutoscaling" TEST_PARALLEL_HARDENING=true TEST_DELAY_AFTER_TEST=1 \
11291129
SELENIUM_ENABLE_MANAGED_DOWNLOADS=true LOG_LEVEL=SEVERE SKIP_CHECK_DOWNLOADS_VOLUME=true make test_node_docker
11301130

11311131
test_standalone_docker_video_sidecar: standalone_docker

Video/video_service.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,12 @@ async def stop_recording(self, session: SessionState) -> bool:
507507
return False
508508
session.ffmpeg_process = None
509509

510-
session.status = SessionStatus.STOPPING
510+
# Only move to STOPPING if we are still in the RECORDING state.
511+
# handle_session_closed() sets status to CLOSED before calling us;
512+
# overwriting that with STOPPING would prevent _cleanup_session_delayed
513+
# from ever cleaning up the session (it checks status == CLOSED).
514+
if session.status == SessionStatus.RECORDING:
515+
session.status = SessionStatus.STOPPING
511516
session.end_time = datetime.now()
512517

513518
try:
@@ -528,9 +533,11 @@ async def stop_recording(self, session: SessionState) -> bool:
528533
# 255 is ffmpeg's own graceful-stop exit code (exit_program(255) in its SIGTERM handler).
529534
if rc not in (0, 255, -signal.SIGTERM, -signal.SIGKILL):
530535
logger.error(f"ffmpeg exited with unexpected code {rc} for {session.session_id}")
536+
session.status = SessionStatus.CLOSED
531537
return False
532538

533539
self.recorded_count += 1
540+
session.status = SessionStatus.CLOSED
534541
duration = session.duration_seconds
535542
logger.info(
536543
f"Stopped recording: session={session.session_id}, " f"duration={duration:.1f}s"
@@ -540,6 +547,7 @@ async def stop_recording(self, session: SessionState) -> bool:
540547
return True
541548
except Exception as e:
542549
logger.error(f"Failed to stop recording for {session.session_id}: {e}")
550+
session.status = SessionStatus.CLOSED
543551
return False
544552

545553
# ==================== Upload Functions ====================
@@ -611,7 +619,12 @@ async def process_upload(self, task: UploadTask) -> None:
611619
except asyncio.TimeoutError:
612620
logger.warning(f"Upload timed out after {self.upload_timeout}s: {task.video_file}, killing process")
613621
proc.kill()
614-
await proc.communicate()
622+
_, stderr_bytes = await proc.communicate()
623+
if stderr_bytes:
624+
logger.debug(
625+
f"Upload stderr at timeout for {task.video_file}: "
626+
f"{stderr_bytes.decode(errors='replace').strip()}"
627+
)
615628
return
616629
finally:
617630
try:
@@ -641,6 +654,10 @@ async def upload_worker(self) -> None:
641654
logger.warning("Upload worker cancelled, pending uploads may be lost")
642655
for t in active_tasks:
643656
t.cancel()
657+
# Await cancelled tasks so they are not left as orphaned
658+
# asyncio tasks (which causes "Task destroyed but pending" warnings
659+
# and makes the active_uploads kill loop in run() the sole cleanup).
660+
await asyncio.gather(*active_tasks, return_exceptions=True)
644661
raise
645662

646663
# None is the sentinel pushed by cleanup() to signal no more uploads

0 commit comments

Comments
 (0)