Go로 확장가능한 WASM 어플리케이션 작성 가능

4 weeks ago 4

  • Go 1.24에서 WebAssembly(Wasm) 관련 기능이 확장됨
  • go:wasmexport 디렉티브가 추가되어 Wasm 모듈 외부에서 Go 함수를 호출할 수 있게 됨
  • WASI를 위한 “reactor” 빌드 모드도 지원되어, 장기간 활성 상태로 코드를 실행할 수 있게 됨
  • 이를 통해 Wasm 환경에서 Go 애플리케이션을 더 유연하게 확장할 수 있는 가능성이 열림

WebAssembly and the WebAssembly System Interface

  • WebAssembly는 웹 브라우저에서 고성능의 저수준 코드를 실행하기 위해 만들어진 이진 포맷임
  • 현재는 브라우저 외부에서도 광범위하게 활용되고, WebAssembly System Interface(WASI)를 통해 시스템 리소스와 상호작용 가능함
  • Go는 1.11 버전에서 js/wasm 포트를 통해 Wasm 컴파일을 지원하기 시작했으며, 1.21 버전에서는 새로운 GOOS=wasip1 포트를 통해 WASI 프리뷰 1 시스템 호출 API를 타겟으로 하는 새로운 포트를 추가

go:wasmexport를 사용한 Go 함수의 Wasm Export

  • Go 1.24에서 새로 추가된 go:wasmexport 디렉티브를 통해, Go 함수를 Wasm 모듈 외부에서 호출할 수 있도록 export로 노출 가능함
  • 예: //go:wasmexport add처럼 선언한 뒤 함수를 작성하면, Wasm 호스트가 해당 함수를 호출할 수 있음
  • 이는 cgo의 export 디렉티브와 유사하지만, 더 간단한 메커니즘으로 구현됨

Building a WASI Reactor

  • WASI “reactor”는 지속적으로 작동하며 이벤트나 요청에 반응할 수 있는 WebAssembly 모듈을 의미함
  • Go 1.24에서는 -buildmode=c-shared 옵션을 사용해 WASI reactor 빌드를 지원함
  • 이 빌드 플래그는 링커에게 _start 함수(명령 모듈의 진입점)를 생성하지 말고, 대신 _initialize 함수를 생성하도록 지시함
    • reactor는 _initialize 함수를 통해 초기화가 진행되고, main 함수 대신 이 함수를 먼저 호출해야 함
  • Wazero 같은 런타임과 함께 사용하면, _initialize 호출 후에 export된 함수를 원하는 만큼 재호출할 수 있음
  • 이 방식은 애플리케이션의 플러그인 혹은 확장 기제로 Wasm을 활용하는 환경에서 유용함

호스트와 클라이언트 간의 풍부한 타입 지원

  • Go 1.24에서는 go:wasmimport로 호출되는 함수의 매개변수/반환형에 대해 제약이 완화됨
  • 예를 들어, bool, string, int32 포인터, 구조체 포인터 등을 전달할 수 있음
    • 다만 64비트와 32비트 환경 차이 등으로 여전히 제한이 존재함
  • 이는 Go Wasm 애플리케이션을 보다 자연스럽고 편리하게 작성할 수 있도록 하며, 불필요한 타입 변환을 제거

제한 사항

  • Wasm은 병렬 처리가 없는 단일 스레드 아키텍처
  • go:wasmexport 함수는 새로운 고루틴을 생성할 수 있지만, 백그라운드 고루틴을 생성하는 함수는 go:wasmexport 함수가 반환된 후 Go 기반 Wasm 모듈로 다시 호출될 때까지 실행을 계속하지 않음
  • 일부 타입 제한이 완화되었지만, 여전히 go:wasmimport 및 go:wasmexport 함수와 함께 사용할 수 있는 타입에는 제한이 있음
    • 포인터를 포함한 복합 타입 전달에는 아직 제약 사항이 존재

결론

  • Go 1.24의 WASI reactor 빌드 및 go:wasmexport 기능 추가는 Go의 Wasm 생태계를 크게 확장시키는 개선사항임
  • 이를 통해 개발자가 더 다양한 Go 기반 Wasm 애플리케이션을 만들 수 있도록 하여 Wasm 생태계에서 Go의 새로운 가능성을 열어줌

Read Entire Article