Happy Eyeballs Version 2 알고리즘은 Ruby의 Socket.tcp
메서드에 먼저 적용되었습니다.
Socket.tcp
구현 개선
- 초기 문제점:
Socket.tcp
의 초기 상태 머신 구현은 이름 확인 동시 완료 시에도 순차 처리하여IO.select
의 불필요한 호출과 복잡성을 야기했습니다. - 개선: 명시적 상태 관리를 제거하고,
IO.select
호출을 중앙 집중화했습니다. 모든 이전 연결 시도가 실패한 경우 다음 연결 시도를 즉시 진행하도록connection_attempt_expires
를 리셋하는 로직이 추가되었습니다. 이 개선된Socket.tcp
는 2024년 7월 30일 Ruby 3.4 마스터에 병합되었습니다.
TCPSocket.new
통합 과정
C로 구현된 TCPSocket.new
에 Happy Eyeballs를 적용하는 과정은 기존 C 라이브러리의 제약에 직면했습니다.
* 이름 확인 제약: 기존 이름 확인 함수는 병렬 처리 및 파이프/select
를 통한 연결 대기에 부적합했습니다.
* 전용 메커니즘: init_fast_fallback_inet_sock_internal
함수를 통해 주소 패밀리별 스레드를 생성하고, 파이프와 select
시스템 호출로 이름 확인 및 연결 완료를 동시에 모니터링하는 새로운 메커니즘을 구축했습니다.
주요 결함 및 해결책
- CI 타임아웃:
TCPSocket.new
병합 후Net::HTTP
테스트에서 IPv6 연결 실패 후connection_attempt_delay
로 인한 타임아웃이 발생했습니다. 실패한 연결 시도 후connection_attempt_expires
를 즉시 리셋하여 해결했습니다. FD_SETSIZE
한계:select
시스템 호출의FD_SETSIZE
제한으로 파일 디스크립터 수가 많아질 때 세그멘테이션 폴트가 발생했습니다. Ruby의IO.select
가rb_fd_select
함수를 통해 동적으로fd_set
비트맵을 확장하여 이 문제를 해결하는 것을 확인하고,TCPSocket.new
또한 해당 래퍼 함수를 사용하여 문제를 성공적으로 해결했습니다.