백엔드 개발 Golang Wasm 구성 요소 모델 및 관용적 코드 생성

Wasm 구성 요소 모델 및 관용적 코드 생성

Dec 22, 2024 pm 02:39 PM

The Wasm Component Model and idiomatic codegen

Arcjet은 WebAssembly를 코드 SDK로서의 보안과 함께 번들로 제공합니다. 이를 통해 개발자는 PII 감지 및 봇 감지와 같은 일반적인 보안 기능을 코드에서 직접 구현할 수 있습니다. 대부분의 논리는 기본 성능에 가까운 보안 샌드박스를 제공하고 로컬 우선 보안에 대한 우리 철학의 일부인 Wasm에 내장되어 있습니다.

JavaScript에서 다른 기술 스택까지 지원을 구축할 때 여러 플랫폼에서 동일한 코드를 실행하는 기능도 도움이 되지만, 언어 간 번역을 위해서는 중요한 추상화가 필요합니다(저희 Wasm은 Rust에서 컴파일되었습니다).

WebAssembly 구성 요소 모델은 이를 가능하게 하는 강력한 구조이지만, 구조는 이를 둘러싼 구현 및 도구만큼 우수할 수 있습니다. 구성 요소 모델의 경우 이는 호스트(WebAssembly 구성 요소 모델을 실행하는 환경) 및 게스트(모든 언어로 작성되고 구성 요소 모델로 컴파일된 WebAssembly 모듈, 우리의 경우 Rust)에 대한 코드 생성에서 가장 분명합니다.

컴포넌트 모델은 호스트와 게스트 간의 통신을 위한 언어를 정의하며 주로 유형, 기능, 가져오기 및 내보내기로 구성됩니다. 광범위한 언어를 정의하려고 시도하지만 변형, 튜플 및 리소스와 같은 일부 유형은 특정 범용 프로그래밍 언어에 존재하지 않을 수 있습니다.

도구가 이러한 언어 중 하나에 대한 코드를 생성하려고 할 때 작성자는 구성 요소 모델 유형을 해당 범용 언어에 매핑하기 위해 창의력을 발휘해야 하는 경우가 많습니다. 예를 들어 JS 바인딩을 생성하기 위해 jco를 사용하고 이는 { 태그: 문자열, 값: 문자열 } 형태의 JavaScript 개체를 사용하여 변형을 구현합니다. 결과에 대한 특별한 경우도 있습니다<_, _> 오류 변형이 오류로 바뀌고 발생하는 유형입니다.

이 게시물에서는 Wasm 구성 요소 모델이 언어 간 통합을 가능하게 하는 방법, 호스트와 게스트에 대한 코드 생성의 복잡성, Go와 같은 언어에서 관용적 코드를 달성하기 위해 취하는 절충점을 살펴봅니다.

Go용 호스트 코드 생성

Arcjet에서는 Go 프로그래밍 언어로 작성된 호스트용 코드를 생성하는 도구를 구축해야 했습니다. SDK가 모든 것을 로컬에서 분석하려고 시도하지만 항상 가능한 것은 아니므로 추가 메타데이터로 로컬 결정을 강화하는 Go로 작성된 API가 있습니다.

Go는 설계상 매우 최소한의 구문과 유형 시스템을 갖추고 있습니다. 아주 최근까지 제네릭도 없었고 여전히 상당한 한계가 있습니다. 이로 인해 구성 요소 모델에서 Go로의 codegen이 다양한 방식으로 복잡해집니다.

예를 들어 결과를 생성할 수 있습니다<_, _> 다음과 같이:

type Result[V any] struct {
    value V
    err error
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

단, 이는 오류 위치에 제공할 수 있는 유형을 제한합니다. 따라서 다음과 같이 코드 생성해야 합니다.

type Result[V any] struct {
    value V
    err error
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 방법은 작동하지만 위에서 정의한 Result 유형과 동일한 의미를 나타내기 위해 종종 val, err := doSomething() 규칙을 사용하는 다른 관용적 Go와 함께 사용하기가 번거롭습니다.

게다가 이 Result를 생성하는 것도 번거롭습니다. Result[int, string]{value: 1, err: ""}. Result 유형을 제공하는 대신 Go 사용자가 생성된 바인딩을 자연스럽게 사용하도록 관용적 패턴을 일치시키고 싶을 것입니다.

관용적 매핑과 직접 매핑

언어에 더 자연스럽게 느껴지도록 코드를 생성할 수도 있고 구성 요소 모델 유형에 더 직접적으로 매핑할 수도 있습니다. 두 옵션 모두 사용 사례에 100% 적합하지 않으므로 어느 것이 가장 적합한지 결정하는 것은 도구 작성자의 몫입니다.

Arcjet 툴링의 경우 옵션으로 관용적인 Go 접근 방식을 선택했습니다<_> 결과<_, _> 각각 val, ok := doSomething() 및 val, err := doSomething()에 매핑되는 유형입니다. 변형의 경우 다음과 같이 각 변형이 구현해야 하는 인터페이스를 만듭니다.

type Result[V any, E any] struct {
    value V
    err E
}
로그인 후 복사
로그인 후 복사

이는 유형 안전성과 불필요한 포장 사이의 적절한 균형을 유지합니다. 물론 포장이 필요한 상황도 있지만, 극단적인 경우로 처리할 수 있습니다.

개발자는 관용적이지 않은 패턴으로 인해 장황하고 유지 관리가 어려운 코드로 인해 어려움을 겪을 수 있습니다. 확립된 규칙을 사용하면 코드가 더 친숙하게 느껴지지만 구현하려면 추가 노력이 필요합니다.

우리는 코드베이스를 이동할 때 무엇을 기대할 수 있는지 알 수 있도록 마찰을 최소화하고 팀의 작업을 더 쉽게 만드는 관용적 경로를 선택하기로 결정했습니다.

호출 규칙

도구 작성자가 내려야 할 가장 큰 결정 중 하나는 바인딩의 호출 규칙입니다. 여기에는 가져오기를 컴파일하는 방법/시기, 설정 또는 인스턴스화 및 정리 중에 Wasm 모듈을 컴파일할지 여부를 결정하는 것이 포함됩니다.

Arcjet 코드베이스에서는 성능 최적화를 위해 팩토리/인스턴스 패턴을 선택했습니다. WebAssembly 모듈을 컴파일하는 것은 비용이 많이 들기 때문에 NewBotFactory() 생성자에서 한 번만 수행합니다. 후속 Instantiate() 호출은 빠르고 저렴하므로 프로덕션 워크로드에서 높은 처리량이 가능합니다.

type BotConfig interface {
    isBotConfig()
}

func (AllowedBotConfig) isBotConfig() {}

func (DeniedBotConfig) isBotConfig() {}
로그인 후 복사

소비자는 NewBotFactory(ctx)를 호출하여 이 BotFactory를 한 번 생성하고 이를 사용하여 Instantiate 메서드를 통해 여러 인스턴스를 생성합니다.

func NewBotFactory(
    ctx context.Context,
) (*BotFactory, error) {
    runtime := wazero.NewRuntime(ctx)

    // ... Imports are compiled here if there are any

    // Compiling the module takes a LONG time, so we want to do it once and hold
    // onto it with the Runtime
    module, err := runtime.CompileModule(ctx, wasmFileBot)
    if err != nil {
            return nil, err
    }

    return &BotFactory{runtime, module}, nil
}
로그인 후 복사

팩토리를 구성할 때 Runtime.CompileModule()을 사용하는 것처럼 모듈이 이미 컴파일되어 있으면 인스턴스화가 매우 빠릅니다.

BotInstance에는 구성 요소 모델 정의에서 내보낸 기능이 있습니다.

func (f *BotFactory) Instantiate(ctx context.Context) (*BotInstance, error) {
    if module, err := f.runtime.InstantiateModule(ctx, f.module, wazero.NewModuleConfig()); err != nil {
            return nil, err
    } else {
            return &BotInstance{module}, nil
    }
}
로그인 후 복사

일반적으로 BotInstance를 사용한 후에는 메모리 누수를 방지하기 위해 이를 정리하고 싶습니다. 이를 위해 닫기 기능을 제공합니다.

func (i *BotInstance) Detect(
    ctx context.Context,
    request string,
    options BotConfig,
) (BotResult, error) {
   // ... Lots of generated code for binding to Wazero
}
로그인 후 복사

전체 BotFactory를 정리하려면 해당 BotFactory도 닫을 수 있습니다.

type Result[V any] struct {
    value V
    err error
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 모든 API를 함께 사용하여 이 WebAssembly 모듈에서 함수를 호출할 수 있습니다.

type Result[V any, E any] struct {
    value V
    err E
}
로그인 후 복사
로그인 후 복사

이러한 팩토리 및 인스턴스 구성 패턴은 사용하는 데 더 많은 코드가 필요하지만 Arcjet 서비스의 핫 경로에서 최대한 많은 성능을 달성하기 위해 선택되었습니다.

컴파일 비용을 프론트 로딩함으로써 대기 시간이 가장 중요한 Arcjet 서비스의 핫 경로에서 요청 처리가 최대한 효율적이도록 보장합니다. 이러한 절충안은 초기화 코드에 약간의 복잡성을 추가하지만 요청당 오버헤드가 상당히 낮아지는 이점이 있습니다. 절충점에 대한 논의를 참조하세요.

절충안

두 개 이상의 언어를 통합해야 할 때마다 네이티브 FFI를 사용하든 구성 요소 모델을 사용하든 균형을 맞춰야 합니다.

이 게시물에서는 Arcjet에서 직면한 몇 가지 문제와 결정을 내린 이유에 대해 논의했습니다. 모두가 구성 요소 모델 및 WIT와 같은 동일한 기본 요소 세트를 기반으로 구축하는 경우 wit-bindgen 또는 wit-comComponent와 같은 동일한 고품질 기본 요소 세트를 활용할 수 있습니다. 모든 사용 사례에 적합한 도구를 구축하세요. 이것이 바로 표준을 향한 노력이 모든 사람에게 도움이 되는 이유입니다.

WebAssembly 구성 요소 모델은 언어 간 통합을 위한 강력한 추상화를 제공하지만 해당 유형을 Go와 같은 언어로 변환하려면 미묘한 설계 문제가 발생합니다. 관용적인 패턴을 선택하고 선택적으로 성능을 최적화함으로써(예: 팩토리/인스턴스 패턴 사용) 효율성을 유지하면서 자연스러운 개발자 경험을 제공할 수 있습니다.

구성 요소 모델을 중심으로 한 도구가 발전함에 따라 이러한 통합을 더욱 단순화하는 더욱 세련된 codegen 접근 방식을 기대할 수 있습니다.

위 내용은 Wasm 구성 요소 모델 및 관용적 코드 생성의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

<gum> : Bubble Gum Simulator Infinity- 로얄 키를 얻고 사용하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
Nordhold : Fusion System, 설명
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora : 마녀 트리의 속삭임 - Grappling Hook 잠금 해제 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Golang vs. Python : 성능 및 확장 성 Golang vs. Python : 성능 및 확장 성 Apr 19, 2025 am 12:18 AM

Golang은 성능과 확장 성 측면에서 Python보다 낫습니다. 1) Golang의 컴파일 유형 특성과 효율적인 동시성 모델은 높은 동시성 시나리오에서 잘 수행합니다. 2) 해석 된 언어로서 파이썬은 천천히 실행되지만 Cython과 같은 도구를 통해 성능을 최적화 할 수 있습니다.

Golang 및 C : 동시성 대 원시 속도 Golang 및 C : 동시성 대 원시 속도 Apr 21, 2025 am 12:16 AM

Golang은 동시성에서 C보다 낫고 C는 원시 속도에서 Golang보다 낫습니다. 1) Golang은 Goroutine 및 Channel을 통해 효율적인 동시성을 달성하며, 이는 많은 동시 작업을 처리하는 데 적합합니다. 2) C 컴파일러 최적화 및 표준 라이브러리를 통해 하드웨어에 가까운 고성능을 제공하며 극도의 최적화가 필요한 애플리케이션에 적합합니다.

GOT GO로 시작 : 초보자 가이드 GOT GO로 시작 : 초보자 가이드 Apr 26, 2025 am 12:21 AM

goisidealforbeginnersandsuitableforcloudandnetworkservicesduetoitssimplicity, 효율성, 및 콘크리 론 피처

Golang vs. C : 성능 및 속도 비교 Golang vs. C : 성능 및 속도 비교 Apr 21, 2025 am 12:13 AM

Golang은 빠른 개발 및 동시 시나리오에 적합하며 C는 극도의 성능 및 저수준 제어가 필요한 시나리오에 적합합니다. 1) Golang은 쓰레기 수집 및 동시성 메커니즘을 통해 성능을 향상시키고, 고전성 웹 서비스 개발에 적합합니다. 2) C는 수동 메모리 관리 및 컴파일러 최적화를 통해 궁극적 인 성능을 달성하며 임베디드 시스템 개발에 적합합니다.

Golang의 영향 : 속도, 효율성 및 단순성 Golang의 영향 : 속도, 효율성 및 단순성 Apr 14, 2025 am 12:11 AM

goimpactsdevelopmentpositively throughlyspeed, 효율성 및 단순성.

Golang vs. Python : 주요 차이점과 유사성 Golang vs. Python : 주요 차이점과 유사성 Apr 17, 2025 am 12:15 AM

Golang과 Python은 각각 고유 한 장점이 있습니다. Golang은 고성능 및 동시 프로그래밍에 적합하지만 Python은 데이터 과학 및 웹 개발에 적합합니다. Golang은 동시성 모델과 효율적인 성능으로 유명하며 Python은 간결한 구문 및 풍부한 라이브러리 생태계로 유명합니다.

Golang 및 C : 성능 상충 Golang 및 C : 성능 상충 Apr 17, 2025 am 12:18 AM

Golang과 C의 성능 차이는 주로 메모리 관리, 컴파일 최적화 및 런타임 효율에 반영됩니다. 1) Golang의 쓰레기 수집 메커니즘은 편리하지만 성능에 영향을 줄 수 있습니다. 2) C의 수동 메모리 관리 및 컴파일러 최적화는 재귀 컴퓨팅에서 더 효율적입니다.

공연 경주 : 골랑 대 c 공연 경주 : 골랑 대 c Apr 16, 2025 am 12:07 AM

Golang과 C는 각각 공연 경쟁에서 고유 한 장점을 가지고 있습니다. 1) Golang은 높은 동시성과 빠른 발전에 적합하며 2) C는 더 높은 성능과 세밀한 제어를 제공합니다. 선택은 프로젝트 요구 사항 및 팀 기술 스택을 기반으로해야합니다.

See all articles