얼쑤는 녹음을 받으면 ffprobe를 실행해 오디오 형식과 길이를 확인합니다. 리뷰에서 요청을 처리하는 스레드가 대기 중에 중단되면, 서버 코드가 예외로 빠져나가도 자식 프로세스는 남을 수 있다는 점을 발견했습니다. 사용자의 파일 형식이 잘못된 경우와 검사를 끝낼 수 없었던 경우도 앱에서는 다르게 처리해야 합니다.
예외 경로에서 자식 프로세스 종료
ffprobe의 표준 출력은 별도 스레드가 읽습니다. 부모가 출력을 읽지 않고 종료만 기다리면, 쓰기 버퍼가 찼을 때 자식도 진행할 수 없기 때문입니다. 부모는 프로세스의 종료와 출력 읽기 완료를 각각 기다립니다. 시간 초과나 읽기 실패는 검사 도구의 오류로 처리합니다. 대기 중 인터럽트를 받으면 현재 스레드에 중단 표시를 복구해 상위 코드도 그 상태를 볼 수 있게 했습니다.
정리는 finally에 두었습니다. 해당 호출에서 띄운 프로세스가 살아 있으면 강제 종료를 요청합니다. 예외를 던졌다는 사실만으로는 종료를 확인할 수 없으므로, 테스트는 자식이 실제로 사라질 때까지 상태를 따로 살핍니다.
대역 프로세스의 PID로 종료 확인
가짜 ffprobe는 테스트 JVM과 같은 Java 실행 파일로 띄웠습니다. 실행 인자에 따라 출력하거나 실패 코드로 끝나거나 기다립니다. 기다리는 가짜는 자기 PID를 파일에 씁니다. 시간 초과 테스트에서는 그 PID가 더 이상 살아 있지 않은지 확인했습니다. 인터럽트 테스트는 PID 파일이 생겨 자식이 실행됐음을 확인한 다음 부모 스레드를 중단하고, 중단 표시 복구와 PID 종료를 함께 봤습니다.
정리 코드를 빼자 이 두 테스트가 실패했습니다. 코드를 복원한 뒤 기본 검사 13개가 통과했고 남은 가짜 ffprobe는 0개였습니다. 실제 ffmpeg와 ffprobe를 쓰는 별도의 mediaTest도 5개가 통과했습니다. 출력 읽기 실패를 자동으로 재현하는 검사는 당시 없었고, Java로 만든 대역도 Windows에서 직접 실행한 기록은 없습니다. 확인한 것은 로컬에서 띄운 자식 프로세스의 시간 초과와 중단 경로입니다.

댓글
댓글과 반응은 GitHub 계정으로 로그인해 남길 수 있어요.