2020-11-18(Wed)

  1. 학습 날짜 // 2020-11-18(수)

  2. 학습시간 // 9:00~22:00

  3. 학습 범위 및 주제 // webserv 오류

  4. 동료 학습 방법 // yohai님과 페어프로그래밍, sanam님과 토의

  5. 학습 목표 // CGI 통신시 발생하는 오류의 원인을 확인하여 제거한다.

  6. 상세 학습 내용

![image](https://user-images.githubusercontent.com/54612343/99902794-be8d1180-2d03-11eb-90e5-5c90548be584.png![image](https://user-images.githubusercontent.com/54612343/99903531-5f7dcb80-2d08-11eb-815a-e09f31931e61.png)

문제) CGI pipe에 write 할 때 pipe_broken error는 왜 발생하는걸까, 그리고 어떻게 대처하는가?

해답) 정확한 원인은 확인 못했으나 CGI가 처리하지 못할 속도로 write해주면 CGI 실행 프로세스가 종료되는 듯하다. usleep으로 테스터 CGI에 write하는 속도를 조절해주자 해결되었다.

물론 write 대상 fd가 닫힌 상태인데 불구하고 write할 때 발생하는 것임을 알지만, CGI pipe는 닫은 적이 없다. 그럼 도대체 왜 문제가 생기는 걸까??

솔직히 말하면 완벽하게 원인을 알아낸 것은 아니다. 하지만 추정은 해볼 수 있다.

  1. write하는 중에 발생하는 broken_pipe 는 write 대상 fd가 닫혔을 경우에 발생한다.

  2. 그러나 나는 pipe의 side_in을 닫은 적이 없다. 그렇다면?

  3. 아마 자식프로세스, 그러니까 CGI 실행프로세스에서 파이프를 닫았거나 프로세스가 종료되어 exit가 실행되어 자원이 반환되었을 것이다.

재밌는게 이는 우리가 CGI에 write 해주는 속도를 usleep으로 완급조절해주면 얼추 해결된다는 것이다. 예상컨데 CGI가 pipe buffer로부터 read하는 것보다 서버가 pipe buffer에 write하는 속도가 훨씬 빠르면 문제가 생기는 것 아닐까 싶다. 테스터로 주어진 CGI가 read를 해오는 속도가 좀 느린 탓에 버퍼가 터지는건 아닐까? pipe buffer가 가득찼다면 write할 때 blocking 되지만, 우리는 non-blocking 되고 있으니.. 이 부분은 send에 MSG_DONTWAIT 옵션을 두면 errno로 관측 가능한데, subject에서 errno 관측을 금하고 있으므로 대안이 되지 않을 것 같다. (엄밀히 말하면 read/write 중 errno 관측만 금하고 있는 것 같기도 한데.. subject가 참 모호하다;)

  1. 학습 내용에 대한 개인적인 총평

후 usleep쓰는 것은 뭔가 우아하지 않은 방법으로 느껴지는데 쓰고 말았습니다. write와 read의 속도가 다르다는 점은 알고 있었지만 buffer에 대한 지식이 부족한 것을 느꼈습니다. 특히 non-blocking상황에서 계속 write를 하거나 read를 하면 어떤 현상이 일어나는지는 명확히 모르네요, 서칭능력이 부족한지 errno가 던져지는 것 외에 broken_pipe 에러가 발생할만한 일은 철저히 추측해서 해결했습니다. 테스터로 주어진 cgi tester가 어떤 코드로 구현되어있는지 안다면 도움이 될텐데, 리버스 엔지니어링이라도 해봐야하나?! 싶었습니다ㅎㅎ 물론 알만한 분한테 물어보는걸 먼저 해야겠습니다.

다음 학습 계획

  • CGI 통신

Last updated