Dev log #21 Hardening WebRTC-Direct and solving SCM leaks
이번 주에는 Python 기반 libp2p의 WebRTC-Direct 상호운용성 문제와 소켓 누수를 수정하고, Go 기반 agent-orchestrator의 파일 경로·GitHub SCM 폴링 문제를 다뤘습니다. ICE 자격 증명 경쟁 조건, 연결 종료 누수, 잘못된 PR 재조회, .git/info/exclude 누적 문제를 포함해 8개 커밋과 11개 PR을 진행했습니다.
AI 요약
이번 작업은 분산 시스템을 연결하는 네트워크·파일 시스템·소스 코드 관리(SCM) 계층의 문제를 함께 다룬 기록입니다. 작성자는 Python 구현체인 py-libp2p와 Go 기반 agent-orchestrator를 오가며 총 8개 커밋과 11개 PR을 진행했습니다. 핵심은 WebRTC-Direct가 서로 다른 언어 구현 사이에서 안정적으로 동작하도록 만드는 일과, 장시간 실행되는 노드 및 에이전트 개발 환경에서 자원과 저장소 상태가 누적되거나 어긋나지 않도록 하는 일이었습니다.
■ py-libp2p의 WebRTC-Direct 상호운용성 개선
py-libp2p에서는 이번 주 6개 커밋을 진행했으며, 대부분 WebRTC-Direct 전송 계층 안정화에 집중했습니다. 가장 큰 문제는 WebRTC 다이얼러의 경쟁 조건(race condition)이었습니다. 첫 번째 접촉(first-contact) 재생 과정이 시작되기 전에 ICE(Interactive Connectivity Establishment) 자격 증명이 올바르게 설정되지 않는 경우가 있었고, 이 문제가 Go 노드와 Python 노드 사이의 상호운용성을 막고 있었습니다. 각 구현체를 따로 실행하면 동작하지만 실제로 서로 연결할 때 실패하는 유형의 문제였으며, 작성자는 연결 절차에서 ICE 자격 증명이 필요한 시점에 준비되도록 수정했습니다.
WebRTC-Direct 리스너 쪽에서는 진정한 ICE-Lite listener를 추가하는 PR #1532도 열었습니다. 이 변경은 166줄이 추가되는 규모이며, WebRTC-Direct가 연결을 수락하는 쪽의 동작을 더 견고하게 만드는 것을 목표로 합니다. 관련 작업은 Issue #1512로도 추적하고 있으며, 처음에는 있으면 좋은 기능으로 시작했지만 적절한 WebRTC-Direct 지원을 위해 필요한 기능으로 범위가 커졌다고 설명합니다.
문서 작업도 병행했습니다. PR #1513에서는 STUN listener와 SDP harness의 차이를 문서화하고, v1과 v2 다이얼링 방식에 대한 지침을 추가했습니다. 작성자는 P2P 기본 구성 요소를 다룰 때 명확한 문서가 코드 품질만큼 중요하다고 봅니다. 또한 Gossipsub 비교와 독립 실행 예제를 추가하는 PR #1139를 검토하면서 변경을 요청했습니다. Gossipsub은 복잡한 기능인 만큼, 새로운 사용자를 안내하는 예제가 오해를 만들지 않도록 충분히 견고해야 한다는 판단입니다.
■ 연결 종료와 소켓 누수 정리
네트워크 계층의 또 다른 초점은 mplex와 swarm에서 발생하는 소켓 누수였습니다. 보안 연결이 닫히지 않은 채 남아 있으면 장시간 실행되는 노드가 결국 파일 디스크립터(file descriptor)를 소진할 수 있습니다. 작성자는 종료 과정에서 보안 연결뿐 아니라 그 아래의 실제 소켓까지 해제되도록 수정했으며, 연결 종료 문제와 WebRTC 다이얼 문제를 다룬 PR #1497과 PR #1495가 반영됐습니다.
아직 해결해야 할 누수도 Issue #1498에서 추적하고 있습니다. 테스트 스위트에 잔존하는 미종료 소켓 누수 때문에 filterwarnings guard를 활성화하지 못하고 있습니다. 테스트가 자원을 누수하지 않는다는 점을 보장하기 전에는 더 엄격한 CI 검사를 켤 수 없기 때문입니다. 작성자는 이 작업이 눈에 띄는 기능 추가는 아니지만, 자원 경고를 방치해 기술 부채가 커지는 것을 막는 유지보수라고 설명합니다. 다음 주 목표에도 이 테스트 스위트의 소켓 누수 문제를 다시 확인하는 일이 포함되어 있습니다.
■ agent-orchestrator의 파일 경로와 SCM 폴링
Go 기반 agent-orchestrator에서는 개발자 경험과 SCM 통합을 중심으로 작업했습니다. Linux와 macOS에서 백슬래시(backslash)가 포함된 workspace 파일 이름이 잘못 해석되는 엣지 케이스를 수정했으며, 이 변경은 PR #5055로 반영됐습니다. 운영체제별 경로 처리 차이로 인해 한 환경에서는 동작하지만 다른 환경에서는 실패하는 문제를 줄이는 변경입니다.
GitHub 폴링에서는 since 파라미터가 엔드포인트에서 제대로 반영되지 않아 모든 열린 PR을 매번 다시 나열하는 문제가 있었습니다. 이 동작은 에이전트가 GitHub의 변경 사항을 효율적으로 확인하지 못하게 만들 수 있으므로, SCM 폴링 수정 이후에도 에이전트가 저장소 상태를 계속 정확히 따라가는지 확인할 예정입니다.
Copilot adapter와 관련해서는 Issue #5046을 열었습니다. 이 어댑터가 세션마다 .git/info/exclude 파일에 영구적인 한 줄을 추가하고 있었기 때문입니다. 세션이 반복될수록 exclude 파일에 불필요한 항목이 계속 쌓일 수 있는 구조이며, 작성자는 이를 방치할 경우 파일이 크고 지저분해질 수 있다고 지적합니다.
■ PR과 이슈 처리 현황
이번 주에는 총 11개 PR을 다뤘습니다. 이 가운데 4개는 병합됐고, 3개는 열려 있으며, 4개는 닫혔습니다. agent-orchestrator의 PR #5089, #5088, #5057, #5056은 더 나은 구조가 보이거나 수정 방향을 다시 잡을 필요가 있어 닫았습니다. 작성자는 빠르게 반복하는 과정에서 처음 만든 수정안보다 나은 설계가 나오면, 충분하지 않은 변경을 병합하기보다 기존 PR을 닫고 더 나은 PR을 여는 편을 택한다고 설명합니다.
이슈는 6개를 열고 닫았습니다. py-libp2p에서는 ICE-Lite listener 작업을 별도 이슈로 추적했고, 소켓 누수 문제는 테스트의 filterwarnings guard를 막는 원인으로 남아 있습니다. 리뷰는 2건 진행했습니다. py-libp2p의 Gossipsub 예제 PR에는 변경을 요청했고, agent-orchestrator의 Arch Linux 지원 및 시스템 설치 환경에서 자동 업데이트를 중단하는 PR #5137은 승인했습니다. 시스템으로 관리되는 패키지는 애플리케이션이 아니라 패키지 관리자가 업데이트를 담당해야 한다는 이유입니다.
■ 작업 규모와 다음 단계
전체 변경량은 508줄 추가와 41줄 삭제였습니다. 대규모 리팩터링보다는 WebRTC 스택에 기능을 추가하고 기존 연결·자원 관리 버그를 고치는 데 더 많은 시간을 쓴 주간이었습니다. 언어별로는 Python 작업이 중심이었고, 소켓·바이트·프로토콜을 다루는 네트워크 계층에 집중했습니다. Go에서는 SCM API와 파일 시스템 추상화를 다뤘습니다.
다음 주의 우선순위는 py-libp2p의 ICE-Lite listener PR #1532를 마무리하고, 테스트 스위트의 소켓 누수를 다시 점검하는 것입니다. 동시에 agent-orchestrator의 SCM 폴링 수정이 GitHub 상태와 에이전트의 내부 인식을 계속 일치시키는지도 확인할 예정입니다. 이 기록은 WebRTC 연결 절차의 미세한 순서 문제부터 파일 디스크립터 회수, 운영체제별 경로 처리, GitHub API 폴링, Git 설정 파일 누적까지 분산 시스템을 실제로 운영할 때 발생하는 주변부 문제를 구체적인 커밋·PR·이슈 단위로 보여줍니다.
원문: dev.to / 번역·요약: Trawling