2025년 11월 21일 OSS 금요 업데이트: UringMachine 개발 및 Ruby Fiber Scheduler 개선

OSS Friday Update - Noteflakes

작성자
발행일
2025년 11월 21일

핵심 요약

  • 1 Ruby Association 그랜트를 받아 UringMachine gem 개발에 착수했으며, 특히 Ruby의 저수준 io_uring I/O를 Fiber::Scheduler와 통합하는 데 집중하고 있습니다.
  • 2 Fiber::Scheduler 구현 과정에서 Ruby I/O 클래스의 복잡성과 IO 객체별 논블로킹 모드 처리의 불일치, EINTR 문제 등 다양한 기술적 난관을 해결하며 심층적인 학습을 진행했습니다.
  • 3 Ruby Fiber Scheduler 인터페이스 확장을 제안하고, io_uring_prep_waitid API를 활용한 자식 프로세스 대기 개선 방안을 io-event gem에 적용하기 위한 PR을 제출하는 등 활발한 기여를 하고 있습니다.

도입

저자는 최근 바쁜 일정 속에서도 매주 하루를 오픈소스 개발에 할애하기로 결정하고, 그 첫 번째 진행 상황을 공유했습니다. 특히 일본 Ruby Association의 그랜트 수혜자로 선정되어 저수준 io_uring I/O를 Ruby에 통합하는 UringMachine gem 개발에 착수했으며, Ruby 파이버 전문가인 Samuel Williams의 멘토링 아래 프로젝트를 진행하고 있음을 밝힙니다. 이 프로젝트는 Ruby I/O 생태계와 UringMachine의 저수준 API를 연결하는 Fiber::Scheduler 구현에 중점을 둡니다.

본 업데이트는 UringMachine 프로젝트의 주요 진척 사항과 그 과정에서 얻은 기술적 통찰을 상세히 다룹니다.

UringMachine Fiber Scheduler 개발 현황

  • UringMachine은 io_uring 기반의 저수준 I/O API를 제공하며, 파이버를 통한 동시성 및 futex 기반 뮤텍스와 큐를 지원합니다.

  • 표준 Ruby I/O 클래스와의 호환성 문제를 해결하기 위해 Fiber::Scheduler 구현이 필수적임을 인지했습니다.

  • 현재 기본적인 I/O, 슬립, 블로킹 작업 대기(뮤텍스 잠금, 큐 대기) 및 스케줄러 생명주기 관리가 가능한 UringMachineFiber::Scheduler의 기본 버전이 완성되었습니다.

  • io.c 파일의 방대한 코드량(약 1만 라인)에서 알 수 있듯이, Ruby의 IO 클래스 구현은 매우 복잡하며, Fiber::Scheduler 메커니즘을 점진적으로 학습하며 개발을 진행 중입니다.

Fiber Scheduler 작업 중 학습한 내용

  • Kernel.puts 호출 시 후행 개행 문자가 별도의 쓰기 작업으로 처리되며, 동시 쓰기 시 예상치 못한 결과를 초래할 수 있어 IO 인스턴스별 뮤텍스를 사용해 동기화하는 것으로 파악됩니다.

  • IO 객체별 논블로킹(O_NONBLOCK) 동작 불일치:
    • 파일 및 표준 I/O는 블로킹 모드입니다.
    • 파이프, 소켓, OpenSSL 소켓은 논블로킹 모드입니다.
    • io_uring은 블로킹 모드의 파일 디스크립터를 요구하므로, Fiber::Scheduler 구현 시 reset_nonblock 메서드를 통해 IO 인스턴스를 블로킹 모드로 강제 설정하는 코드를 추가했습니다.
  • 다중 파이버 I/O 상황에서 EINTR 예외가 발생하는 현상을 관찰했으며, 이는 시그널에 의한 I/O 작업 중단을 의미하나 정확한 원인은 아직 파악 중입니다.

  • `IO

close 호출 시 뮤텍스가 관여하며 blocking_operation_waitblock 스케줄러 훅이 호출되는 복잡한 메커니즘을 확인했으며, UringMachine의 비동기 close_async` 메서드와 비교하며 추가 분석이 필요합니다.

Fiber Scheduler 인터페이스 개선 및 확장

  • IO 닫기 훅이나 splice 훅 추가 등 Fiber::Scheduler 인터페이스 확장에 대해 Samuel Williams와 논의했습니다.

  • pidfd_open을 활용한 자식 프로세스 대기 시 경쟁 조건 방지 방안을 모색했습니다.

  • io_uring_prep_waitid API를 사용하여 자식 프로세스를 대기하는 방식을 Samuel의 io-event gem에 적용할 것을 제안했으며, 이는 Process.wait와 더 나은 호환성을 제공합니다.

  • Fiber::Schedulerprocess_wait 훅이 Process::Status 인스턴스를 반환해야 하지만, 이 클래스는 직접 인스턴스화할 수 없다는 문제점을 발견하고, Process::Status 객체 생성을 가능하게 하는 PR을 Ruby 4.0 릴리스 전 병합 목표로 제출했습니다. 관련 변경 사항을 io-event gem에도 PR로 제출했습니다.

결론

현재 UringMachine 프로젝트는 `Fiber::Scheduler` 통합의 초기 작동 버전을 구현하고 Ruby I/O 스택의 복잡성을 탐구하는 단계에 있습니다. 저자는 TDD 방식으로 테스트를 추가하며 기능적 완성도와 견고성을 확보할 계획입니다. 저수준 I/O 기능을 Ruby에 도입함으로써 얻을 수 있는 잠재력은 여전히 크며, `Fiber::Scheduler` 인터페이스 개선 및 `io_uring`의 고급 기능을 활용한 자식 프로세스 관리 등 미래 확장에 대한 구체적인 비전을 제시하고 있습니다. 이러한 노력은 Ruby의 비동기 프로그래밍 생태계를 더욱 풍부하게 만들 것입니다.

댓글 0

로그인이 필요합니다

댓글을 작성하거나 대화에 참여하려면 로그인이 필요합니다.

로그인 하러 가기

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!