Ruby와 WebAssembly: 어디서든 Ruby를 실행하다

Yuta Saito, "What you can do with Ruby on WebAssembly"

작성자
EuRuKo
발행일
2025년 01월 13일

핵심 요약

  • 1 RubyWasm 프로젝트는 Ruby를 WebAssembly(Wasm) 기반으로 웹 브라우저부터 엣지 컴퓨팅까지 다양한 플랫폼에서 실행할 수 있도록 지원합니다.
  • 2 이는 C Ruby 인터프리터를 Wasm으로 컴파일하고, Ruby 파일 패키징 및 JavaScript 인터프리테이션 라이브러리 제공을 통해 구현됩니다.
  • 3 특히, Wasm의 최신 컴포넌트 모델을 활용하여 C 확장 라이브러리의 동적 링킹을 지원함으로써 RubyGems와의 호환성을 크게 향상시켰습니다.

도입

본 발표는 Ruby 프로그래밍 언어를 WebAssembly(Wasm) 환경에서 실행 가능하게 하는 RubyWasm 프로젝트에 대해 다룹니다. 발표자인 유타 사오(Yuta Sao)는 Ruby와 Swift 컴파일러의 WebAssembly 지원에 기여하며 RubyWasm 프로젝트를 이끌고 있습니다. WebAssembly는 웹 브라우저뿐만 아니라 IoT, 임베디드 시스템 등 다양한 플랫폼에서 효율적이고 안전하게 프로그램을 실행할 수 있도록 설계된 이식성 높은 바이너리 형식으로, 아키텍처 및 플랫폼 독립성, 효율적인 크기 및 로드 시간, 그리고 신뢰할 수 없는 프로그램의 안전한 실행이라는 장점을 가집니다. 본 발표에서는 RubyWasm의 기본 개념, 실제 활용 사례, 그리고 기술적 구현 세부 사항 및 향후 로드맵을 소개합니다.

WebAssembly의 잠재력

WebAssembly는 프로그램 배포 형식으로서 혁신적인 변화를 가져왔습니다. 웹을 위해 설계되었지만, Wasmtime, Wasm Micro Runtime과 같은 다양한 런타임 구현을 통해 웹 외부에서도 활용됩니다. 특히, 리소스가 제한적인 환경(예: IoT, 임베디드 시스템)에서 Wasm의 경량성과 이식성은 큰 이점을 제공합니다. Wasm은 호스트 시스템에 대한 안전한 접근을 허용하며, SaaS 플랫폼이나 플러그인 시스템과 같이 사용자로부터 신뢰할 수 없는 프로그램을 입력받아 안전하게 실행해야 하는 시스템에 유용합니다. 이는 Wasm이 JSON이 데이터 교환의 표준이 된 것처럼 프로그램 공유의 사실상 표준이 될 잠재력을 가지고 있음을 시사합니다.

RubyWasm 프로젝트 소개

RubyWasm은 Ruby를 WebAssembly를 통해 ‘어디서든’ 실행 가능하게 하는 프로젝트입니다. 여기서 ‘어디서든’은 웹 브라우저뿐만 아니라 비 브라우저 환경까지 포함합니다. 이 프로젝트는 세 가지 주요 구성 요소로 이루어집니다: 1. C 인터프리터의 WebAssembly 컴파일: CRuby를 Wasm으로 컴파일하는 과정은 예외 처리, 파이버(fiber), GC(Garbage Collection) 등의 기능 때문에 쉽지 않았습니다. 현재는 as-f-instrumentations와 같은 후처리 링킹 최적화 기법을 활용하여 이식성을 확보했으나, 성능과 코드 크기 측면에서 개선이 필요하며, 최신 Wasm 기능을 활용하여 이를 개선할 계획입니다. 2. Ruby 파일 및 Gem 패키징 시스템: Wasm 환경에서는 모든 것을 단일 바이너리로 패키징해야 합니다. RubyWasm은 가상 파일 시스템(VFS)을 구현하여 rbwm 명령어를 통해 Gemfile에 명시된 Ruby Gem들을 Wasm 바이너리로 패키징할 수 있도록 합니다. 3. JavaScript 인터프리테이션 라이브러리: JavaScript 함수 호출 및 Promise 처리를 Ruby 코드 내에서 동기적으로 작성할 수 있도록 지원합니다.

RubyWasm 활용 사례

RubyWasm은 다양한 고급 기능을 시연합니다: * 브라우저 내 IRB 실행: 웹사이트에서 IRB(Interactive Ruby)를 직접 실행할 수 있으며, xterm.js와의 통합을 통해 자동 완성 및 이스터 에그와 같은 완전한 기능을 갖춘 터미널 에뮬레이션을 제공합니다. * 브라우저 내 Mastodon 실행: Ruby on Rails 기반의 대규모 오픈소스 애플리케이션인 Mastodon을 브라우저 내에서 구동하는 시연은 RubyWasm의 C 확장 라이브러리 및 Active Record 지원의 견고함을 보여줍니다. Mastodon 앱은 서비스 워커(Service Worker)에서 실행되며, 웹 페이지의 네트워크 요청을 가로채 Rack 인터페이스를 통해 응답합니다. 놀랍게도 PostgreSQL 데이터베이스 또한 브라우저 내에서 실행되어 Active Record와 통신합니다. * 커뮤니티 제공 사례: Ruby Gem을 웹사이트에서 설치 없이 테스트할 수 있는 Playground와 같은 커뮤니티 프로젝트들이 RubyWasm의 잠재력을 보여줍니다.

기술적 세부 사항: C 확장 동적 링킹

C 확장 라이브러리를 Wasm으로 크로스 컴파일하는 것은 중요한 과제입니다. Ruby 생태계의 핵심인 mkmf는 C 확장 빌드 시스템의 중심이며, RubyGems는 이를 사용하여 C 확장이 포함된 Gem을 빌드합니다. 발표자는 mkmf와 RubyGems 자체에 네이티브 크로스 컴파일 지원을 추가하여 Ruby 3.4부터는 크로스 컴파일이 더 용이해질 것이라고 설명했습니다.

컴파일된 라이브러리를 CRuby 인터프리터에 링킹하는 방법에는 정적 링킹과 동적 링킹이 있습니다. 기존에는 내장 확장(예: Json)에 정적 링킹을 사용했지만, Ruby Gem 시스템을 지원하기 위해 동적 링킹을 채택했습니다. 전통적인 동적 링킹 API가 Wasm에 표준으로 존재하지 않아 문제가 있었으나, 최근 WebAssembly 커뮤니티에서 개발 중인 컴포넌트 모델(Component Model)이 해결책을 제시했습니다. 컴포넌트 모델의 핵심 기능인 모듈 링킹(Module Linking)은 여러 Wasm 모듈을 단일 바이너리에 임베드하고, 모듈 간의 링킹 방식을 정의할 수 있게 합니다. 이를 기반으로 ‘선행 동적 링킹(Ahead-of-Time Dynamic Linking)’ 메커니즘을 구축하여, 빌드 시점에 링킹을 완료하고 최종 바이너리는 완전히 자체 포함되도록 합니다. 이는 런타임에 파일 기반 라이브러리 검색 없이 DL open과 같은 기능을 제한적으로 사용할 수 있게 합니다.

결론

RubyWasm 프로젝트는 Ruby를 WebAssembly 환경에서 성공적으로 실행시키며, RubyGems 및 C 확장 라이브러리 지원을 통해 그 활용 범위를 넓혔습니다. 특히 WebAssembly의 최신 기술인 컴포넌트 모델을 적극적으로 활용하여 동적 링킹과 같은 복잡한 문제를 해결하고 있습니다. 발표자는 향후 로드맵으로 바이너리 크기 최적화, 런타임 성능 향상, 그리고 WebAssembly를 '일반적인 플랫폼'으로 만드는 데 집중할 것이라고 밝혔습니다. RubyWasm은 Ruby를 더욱 WebAssembly 친화적으로 만들기 위한 지속적인 노력을 통해, Ruby 개발자들이 웹 브라우저부터 엣지 컴퓨팅까지 다양한 환경에서 Ruby 애플리케이션을 배포할 수 있는 새로운 가능성을 열어주고 있습니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

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