Fiber 및 Scheduler의 이해
-
Fiber: Ruby에서 일시 중지 가능한 경량 실행 단위입니다. 스레드와 달리 협력적으로 제어권을 양보하며, I/O 바운드 작업에 효율적입니다.
-
Scheduler: 파이버의 실행 시점을 관리하는 역할을 합니다. 파이버가 I/O 작업을 수행할 때 스케줄러는 해당 파이버를 일시 중지하고 다른 파이버를 실행하여 블로킹 없이 비블로킹 I/O를 가능하게 합니다.
Async젬이 대표적인 스케줄러의 예시입니다.
Ruby 3.1 이전의 문제점
IO.select는 여러 파일 디스크립터(소켓, 파일 등)를 모니터링하고 준비될 때까지 기다리는 시스템 호출입니다. Ruby 3.1 이전에는 IO.select가 파이버 내에서 호출될 경우 스레드 전체를 블로킹하여 스케줄러가 다른 파이버를 관리하는 것을 방해했습니다. 이는 IO.select를 사용하는 모든 라이브러리의 동시성 기능을 저해하는 주요 원인이었습니다.
해결책: `Fiber::Scheduler
io_select` 훅
Ruby 3.1은 `Fiber::Scheduler
io_select를 추가하여 이 문제를 해결했습니다. 이제 IO.select가 호출될 때 Ruby는 스케줄러에게 작업을 위임하며, 스케줄러는 비블로킹 방식으로 I/O 다중화를 처리합니다. 이로써 IO.select가 블로킹 없이 작동하고 다른 파이버들이 계속 실행될 수 있게 됩니다. 스케줄러는 io_select(readable, writable, exceptional, timeout)` 메서드를 구현하여 준비된 디스크립터 배열을 반환합니다.
실제적인 영향
-
레거시 호환성:
IO.select를 사용하는 기존 라이브러리들이 파이버 스케줄러와 자동으로 호환됩니다. -
코드 변경 불필요: 기존 코드를 수정할 필요 없이 스케줄러가 활성화되면 비블로킹 방식으로 전환됩니다.
-
성능 향상: 애플리케이션이 수천 개의 동시 I/O 작업을 효율적으로 처리할 수 있게 됩니다.
-
예시:
redis-rb젬과 같은 라이브러리도Falcon과 같은 파이버 기반 웹 서버에서 수정 없이 원활하게 작동합니다.