Juicycrunch Carrot Blog
목록으로
Essay수정

README 에 내 이름이 올라간 날

작은 Issue 하나를 시작으로 오픈소스에 처음으로 간접적인 기여를 해본 경험을 기록합니다

간혈적인 문제 발생

현장에서 연락이 왔습니다.

간헐적으로 처리를 못하고 화물이 리젝 라인으로 빠진다.

개발자는 이미 퇴사한 상태였고, 그동안의 기록을 살펴보았습니다. 혹시나 단서가 될 만한 것이 있을까 싶었습니다.

이미 이 이슈에 대해서는 여러 번 이야기가 올라왔던 것 같습니다. 당시의 판단으로는 인프라를 의심하고 있었습니다. 노이즈, 네트워크 장비, PLC 등.

저 역시 코드를 살펴보았습니다. PLC와 메시징하는 부분, 전달받은 메시지를 처리하는 부분의 로직은 아무리 봐도 문제가 있어 보이지 않았습니다. 로그에서도 특별한 점은 발견되지 않았습니다.

그러던 중 SuperSimpleTcp라는 라이브러리가 눈에 들어왔습니다.

소켓 통신을 주로 .NET에서 제공하는 기본 기능으로 다뤄왔던 터라 오히려 더 눈에 들어왔던 것 같습니다.

테스트를 해보자

똑같은 설정의 소켓 클라이언트와 서버를 만들고, 기존 핸들러 로직을 복사해 아주 단순한 테스트 환경을 만들어봤습니다.

그리고 중복된 메시지를 여러 번 전송해보았습니다.

정말 간헐적으로 Receive 핸들러에서 세그먼트 조립이 실패하고 있었습니다.

이전 기록을 보고 저 역시 내심 인프라 문제라고 생각하고 있었는데, 정작 문제는 소프트웨어에 있었습니다.

문제가 되는 지점은 찾았습니다.

하지만 조금 특이한점이 있었습니다.

왜 Thread 2개가 동시에 진입했지?

SuperSimpleTcp 라이브러리를 조금 더 깊게 살펴보았습니다.

멀티쓰레드구나!

SuperSimpleTcp 에서는 UseAsyncDataReceivedEvents 의 기본값이 true 였고 이로 인해 DataReceived 핸들러가 여러 스레드에서 동시에 실행될 수 있었습니다.

그렇다면 일단 해결 방법은 단순합니다. 해당 옵션을 끄면 됩니다.

하지만 조금 의아했습니다.

Socket 통신을 다룰 땐 세그먼트를 조립하는 로직이 절대 빠질수가 없습니다. 그리고 그 중간에 다른 스레드가 개입해서는 안 됩니다. 이 부분 만큼은 동기적으로 처리되야하는 부분입니다.

네트워크 버퍼를 아무리 크게 잡는다고 해도 한 번의 수신에서 메시지가 완성되어 온다는 보장은 없기 때문입니다.

다시 정리해보니 원인은 명확해졌습니다.

UseAsyncDataReceivedEvents의 기본값이 true였고 이로 인해 DataReceived 핸들러가 동시에 실행될 수 있었습니다.

그 과정에서 메시지 세그먼트를 조립하던 상태가 서로 섞였고 결과적으로 수신 데이터가 마치 노이즈처럼 보이는 문제가 발생했습니다.

조금 허탈했습니다. 노이즈로 판단되었을 때 로그라도 남아 있었다면 조금 더 쉽게 찾을 수 있었을 텐데.

어찌 됐든 원인은 파악했고 현장의 문제도 해결할 수 있었습니다.

이슈 등록

새벽 잠이안와 뒤척이고 있는데 문득 그때 사용했던 라이브러리와 문제가 생각났습니다. GitHub에 들어가 코드를 먼저 확인해보았습니다. 코드는 제가 당시 원인이라고 생각했던 부분이 그대로였습니다.

그러다 문득 Github Issue 로 남겨볼까? 하는 생각이 들었습니다. 누군가 저 처럼 고생하지 않기를 바라는 마음도 있었습니다.

지구 반대편 개발자

사실 등록하고 나서는 별 기대를 하지 않았습니다. 그저 혹시라도 다른 사람이 비슷한 문제를 겪고 있었다면 도움이 되겠다는 정도였습니다.

SuperSimpleTcp README

그런데 수시간 후 답변이 달렸습니다. 지구 반대편에 있는 개발자가 제가 작성한 Issue를 읽고 반영하였습니다. 그리고 v3.1.1 의 README 와 코드 주석에 제 이름이 적혀있었습니다.

간접적이지만 오픈소스에 기여를 했다는거에 무언가 기뻣습니다.

작은 흔적

제가 무엇을 한건 아닙니다.

코드를 직접 수정해서 PR 을 보낸것도 아니고 그저 이상한점을 발견하고 재현해보고 그 내용을 Issue 로 남겼을 뿐입니다.

그런데 그 작은 이슈 하나가 지구 반대편의 개발자에게 전달되고 실제 코드 변화로 이루어졌습니다. 그 과정이 즐거웠습니다.

언젠가는 저도 오픈소스 세상에서 누군가의 이슈에 답변을 남기는 개발자가 되고 싶습니다. 이번 경험이 그 첫걸음이 되면 좋겠습니다.