Go에서 Wasi 지원을 통해 걸어 가십시오

Go에서 Wasi 지원을 통해 걸어 가십시오

Go 1.21은 새 새를 통해 WASI 미리보기 1 Syscall API를 대상으로하는 새로운 포트를 추가합니다. GOOSwasip1. 이 포트는 Go 1.11에 도입 된 기존 웹 해제 포트를 구축합니다.

WebAssembly는 무엇입니까?

WASM (WebAssembly)은 원래 웹 용으로 설계된 이진 명령어 형식입니다. 이는 개발자가 웹 브라우저에서 근처의 속도로 직접 고성능 저수준 코드를 실행할 수있는 표준을 나타냅니다.

Go는 1.11 릴리스에서 WASM으로 컴파일에 대한 지원을 처음으로 추가했습니다. js/wasm 포트. 이를 통해 GO 컴파일러를 사용하여 웹 브라우저에서 실행될 GO 코드가 컴파일되었지만 JavaScript 실행 환경이 필요했습니다.

WASM의 사용이 증가함에 따라 브라우저 외부에 사용 사례가 있습니다. 많은 클라우드 제공 업체가 이제 사용자가 WASM 실행 파일을 직접 실행할 수있는 서비스를 제공하여 새로운 WebAssembly System Interface (WASI) SyScall API를 활용할 수 있습니다.

WebAssembly 시스템 인터페이스

WASI는 WASM 실행 파일에 대한 SYSCALL API를 정의하여 파일 시스템, 시스템 클럭, 임의의 데이터 유틸리티 등과 같은 시스템 리소스와 상호 작용할 수 있습니다. WASI 사양의 최신 릴리스가 호출됩니다 wasi_snapshot_preview1우리가 도출합니다 GOOS 이름 wasip1. 새로운 버전의 API가 개발 중이며 향후 GO 컴파일러에서 지원하면 새로운 추가를 의미 할 수 있습니다. GOOS.

WASI의 생성으로 인해 여러 WASM Runtimes (호스트)가 주변의 SyScall API를 표준화 할 수있었습니다. WASM/WASI 호스트의 예로는 WASMTIME, WAZERO, WASMEDGE, WASMER 및 NODEJS가 있습니다. WASM/WASI 실행 파일 호스팅을 제공하는 많은 클라우드 제공 업체도 있습니다.

GO와 함께 어떻게 사용할 수 있습니까?

최소한 버전 1.21의 GO를 설치했는지 확인하십시오. 이 데모를 위해 Wasmtime 호스트를 사용하여 이진을 실행합니다. 단순한 것으로 시작합시다 main.go:

package main

import "fmt"

func main() {
    fmt.Println("Hello world!")
}

우리는 그것을 위해 그것을 만들 수 있습니다 wasip1 명령 사용 :

$ GOOS=wasip1 GOARCH=wasm go build -o main.wasm main.go

이것은 파일을 생성하고 main.wasm 우리가 실행할 수 있습니다 wasmtime:

$ wasmtime main.wasm
Hello world!

그것이 WASM/WASI로 시작하는 데 필요한 전부입니다! 당신은 그냥 작업하기위한 거의 모든 기능을 기대할 수 있습니다. wasip1. WASI가 GO와 함께 작동하는 방법에 대한 자세한 내용은 제안을 참조하십시오.

WASIP1로 GO 테스트를 실행합니다

Go 1.24는 WASM 지원 파일을 이동했습니다 lib/wasm. Go 1.21-1.23의 경우 사용하십시오 misc/wasm 예배 규칙서.

이진을 구축하고 실행하는 것은 쉽지만 때로는 실행할 수 있기를 원합니다. go test 바이너리를 수동으로 빌드하고 실행하지 않고도 직접. 와 비슷합니다 js/wasm PORT, GO 설치에 포함 된 표준 라이브러리 배포에는이를 매우 쉽게 만드는 파일이 제공됩니다. 추가 lib/wasm 귀하의 디렉토리 PATH GO 테스트를 실행할 때는 선택한 WASM 호스트를 사용하여 테스트를 실행합니다. 이것은 작동합니다 go test 자동으로 실행 lib/wasm/go_wasip1_wasm_exec 이 파일을 찾을 때 PATH.

$ export PATH=$PATH:$(go env GOROOT)/lib/wasm
$ GOOS=wasip1 GOARCH=wasm go test ./...

이것은 실행됩니다 go test wasmtime 사용. 사용 된 WASM 호스트는 환경 변수를 사용하여 제어 할 수 있습니다. GOWASIRUNTIME. 이 변수의 현재 지원되는 값은 현재입니다 wazero,,, wasmedge,,, wasmtime그리고 wasmer. 이 스크립트는 GO 버전 간의 변경 사항을 깨뜨릴 수 있습니다. 이동하십시오 wasip1 Binaries는 아직 모든 호스트에서 완벽하게 실행되지 않습니다 ( #59907 및 #60097 참조).

이 기능은 사용할 때도 작동합니다 go run:

$ GOOS=wasip1 GOARCH=wasm go run ./main.go
Hello world!

Go와 함께 wasm 기능을 포장합니다 : Wasmimport

새로운 것 외에 wasip1/wasm Port, Go 1.21은 새로운 컴파일러 지침을 소개합니다. go:wasmimport. 컴파일러는 주석화 된 함수로 호출을 호스트 모듈 이름 및 함수 이름으로 지정된 함수로 통화로 변환하도록 지시합니다. 이 새로운 컴파일러 기능은 우리가 wasip1 Syscall API는 새로운 포트를 지원하기 위해 이동하지만 표준 라이브러리에서 사용되는 것은 국한되지 않습니다.

예를 들어, WASIP1 SYSCALL API는 random_get 함수 및 런타임 패키지에 정의 된 기능 래퍼를 통해 GO 표준 라이브러리에 노출됩니다. 다음과 같이 보입니다.

//go:wasmimport wasi_snapshot_preview1 random_get
//go:noescape
func random_get(buf unsafe.Pointer, bufLen size) errno

그런 다음이 기능 래퍼는 표준 라이브러리에서 사용하기 위해보다 인체 공학적 함수로 래핑됩니다.

func getRandomData(r []byte) {
    if random_get(unsafe.Pointer(&r[0]), size(len(r))) != 0 {
        throw("random_get failed")
    }
}

이렇게하면 사용자가 전화 할 수 있습니다 getRandomData 바이트 슬라이스로 결국 호스트 정의로 향합니다. random_get 기능. 마찬가지로 사용자는 호스트 기능에 대해 자신의 포장지를 정의 할 수 있습니다.

랩핑의 복잡성에 대해 자세히 알아 보려면 go:wasmimport 제안.

제한

동안 wasip1 포트는 모든 표준 라이브러리 테스트를 통과하며, 사용자를 놀라게 할 수있는 WASM 아키텍처의 주목할만한 기본 제한이 있습니다.

WASM은 병렬성이없는 단일 스레드 아키텍처입니다. 스케줄러는 여전히 동시에 실행되도록 고루틴을 예약 할 수 있으며 표준 In/Out/Error는 차단하지 않으므로 고어 루틴은 다른 읽기 또는 쓰기를하는 동안 검찰 할 수 있지만 호스트 기능 호출 (위의 예제를 사용하여 임의의 데이터를 요청하는 등)은 호스트 기능 호출이 돌아올 때까지 모든 Goroutines가 차단됩니다.

주목할만한 기능 wasip1 API는 네트워크 소켓의 전체 구현입니다. wasip1 이미 열린 소켓에서 작동하는 기능 만 정의하면 HTTP 서버와 같은 GO 표준 라이브러리의 가장 인기있는 기능 중 일부를 지원할 수 없습니다. Wasmer 및 Wasmedge와 같은 호스트는 연장을 구현합니다 wasip1 API, 네트워크 소켓의 개방을 허용합니다.

이러한 확장은 GO 컴파일러에서 구현되지 않지만 타사 라이브러리가 있습니다. github.com/stealthrocket/net사용하는 go:wasmimport 사용을 허용합니다 net.Dial 그리고 net.Listen 지원되는 WASM 호스트. 이것은 창조를 가능하게합니다 net/http 이 패키지를 사용할 때 서버 및 기타 네트워크 관련 기능.

Wasm의 미래

추가 wasip1/wasm 포트는 우리가 가져 가고 싶은 WASM 기능의 시작일뿐입니다. GO 기능을 WASM으로 내보내는 제안에 대한 문제 추적기를 주시하십시오 (go:wasmexport), 32 비트 포트 및 미래의 WASI API 호환성.

참여하십시오

당신이 실험을하고 있고 WASM에 기여하고 싶다면, 참여하십시오! Go Issue 트래커는 모든 진행중인 작업을 추적하며 Gophers Slack의 #WeeBassembly 채널은 Go 및 WebAssembly를 논의하기에 좋은 장소입니다. 우리는 당신의 의견을 기다리겠습니다!


Johan Brandhorst-Satzkorn, Julien Fabre, Damian Gryski, Evan Phoenix 및 Achille Roussel

이 기사는 사용할 수 있습니다 GO 블로그 CC에 따라 4.0 증서 라이센스.

Unsplash의 Neom의 사진

출처 참조

Post Comment

당신은 놓쳤을 수도 있습니다