문제의 발견
최근에 subprocess를 사용해서 특정 프로그램에서 주는 stdout(출력값)을 사용해서 가공해야하는 기능을 만드는 중간에 내가 직접 실행하고 그 다음 덤프해서 가져오면 사용이 되는데 내가 만든 스크립트로 실행을 하면 출력결과가 중간에 끊어지는 문제가 생겼다.
그렇다고 Brokenpipe문제는 아닌거 같은게 subprocess가 발견해주는 오류 범위라 오류메시지가 뜨진 않는다.
고민을 해보다가 대충 다음 내세운 문제는 다음과 같다.
1. subprocess로 실행했을 때 허용하는 리소스 크기가 정해져있다.
2. subprocess 출력결과를 실시간으로 받아오는 중 버퍼에 문제가 생겼다.
3. 해당 스크립트가 먼저 종료되어서 즉 부모 프로세스가 먼저 종료되어 파이프 종료가 먼저 종료됨.
문제 상황에 대한 고찰
이는 과정에서 문제가 생긴거라 처음에는 Popen과 run의 비동기와 동기적인 차이인줄알고 특정 클래스의 함수를 바꾸면 될줄 알았는데 동기적으로 실행되는데도 문제가 진행중이었다.
2번과 같은 상황은 비동기에서 더 자주 일어나므로 3번과 같은문제 인줄 알았는데 해당 프로세스들은 동기적으로 잘 동작하고있었기에 3번은 상황은 아니라고 생각했다.
1번을 고민한 이유는 해당 출력값을 가져와야하는 즉 subprocess로 실행시키는 자식 프로세스가 fork를 통해서 여러개의 자원을 차지하기 리소스가 커져서 중간에 종료되는 상황이 있을 수도 있다고 생각을 했다.
실제로 사이즈가 크고 리소스 먹방 찍는 프로그램을 외부호출로 실행했을때 문제가 발생한 적이 있다.
자주 일어나는 상황은 아니지만 리소스를 무작정 먹는거를 해결하는 것 보다는 다른 방법을 택해서 문제를 해결했던 기억이 있다.
로컬에서 일어나는 기능을 만드는 경우에는 database에의한 데이터를 쓰는것 보다는 OS나 해당 로컬에 파일 및 데이터를 사용하는 일이 더 많기에 규격화된 해결방법이 존재하지는 않는 것 같다.
문제의 해결
위에서 본 것중에 정적 분석 해본 결과 문제는 2번 상황과 3번 상황이 겹친듯하다.
동기적으로 잘 동작하지만 중간에 데이터가 끊겼다가 다시 들어오는 구간이 존재하는데 해당 구간에서 이미 출력 결과를 다 읽어서 해당 프로세스가 종료되었다고 판단하여 종료된 것이다. 뭐 subprocess도 기본 통신은 pipe겠지만 버퍼에 데이터가 다 읽어서 사이즈 0 이되면 다 읽은것으로 처리 되는 부분에서 문제가 생긴 것. 해당 부분을 수정해서 데이터가 끊겼다가 들어와도 종료되지 않고(버퍼에 들어올 데이터가 남았다면) 프로세스가 종료되지 않고 유지되도록 하여 해결 하였다.
멀리서 보면 아무것도 아닌 문제인데 당시에는 왜그런지 왜 안되는지 뭐가 문제인지 실마리 조차 잡기 어려웠던 것 같다.
'회사' 카테고리의 다른 글
[TIL 50] windows defender로 인한 파일 삭제 (0) | 2025.03.13 |
---|