検索
ホームページバックエンド開発GolangWasm コンポーネント モデルと慣用的な codegen

The Wasm Component Model and idiomatic codegen

Arcjet には、WebAssembly と Security as Code SDK がバンドルされています。これは、開発者が PII 検出やボット検出などの一般的なセキュリティ機能をコードに直接実装するのに役立ちます。ロジックの多くは Wasm に埋め込まれており、ネイティブに近いパフォーマンスを備えた安全なサンドボックスを提供し、ローカルファースト セキュリティに関する私たちの哲学の一部です。

プラットフォーム間で同じコードを実行できる機能も、JavaScript から他の技術スタックへのサポートを構築する際に役立ちますが、言語間で変換するには重要な抽象化が必要です (Wasm は Rust からコンパイルされています)。

WebAssembly コンポーネント モデル はこれを可能にする強力な構造ですが、その構造はそれを囲む実装とツールによってのみ優れています。コンポーネント モデルの場合、これはホスト (WebAssembly コンポーネント モデルを実行する環境) とゲスト (任意の言語で記述され、コンポーネント モデルにコンパイルされた WebAssembly モジュール。この場合は Rust) のコード生成で最も明らかです。

コンポーネント モデルは、主に型、関数、インポート、エクスポートで構成されるホストとゲスト間の通信用の言語を定義します。幅広い言語を定義しようとしていますが、バリアント、タプル、リソースなどの一部の型は、特定の汎用プログラミング言語に存在しない可能性があります。

ツールがこれらの言語のいずれかのコードを生成しようとする場合、作成者は多くの場合、コンポーネント モデル タイプをその汎用言語にマッピングするために創造性を発揮する必要があります。たとえば、JS バインディングの生成には jco を使用します。これにより、{ タグ: 文字列、値: 文字列 } の形式の JavaScript オブジェクトを使用してバリアントが実装されます。結果には特殊なケースもあります<_ _>エラーのバリアントが Error に変換されてスローされるタイプ。

この投稿では、Wasm コンポーネント モデルが言語間の統合をどのように可能にするか、ホストとゲストのコード生成の複雑さ、Go などの言語で慣用的なコードを実現するために行うトレードオフについて説明します。

Go 用のホスト コード生成

Arcjet では、Go プログラミング言語で書かれたホスト用のコードを生成するツールを構築する必要がありました。私たちの SDK はすべてをローカルで分析しようとしますが、それが常に可能であるとは限らないため、Go で書かれた API を用意し、追加のメタデータでローカルの決定を強化します。

Go は設計上、非常に最小限の構文と型システムを備えています。ごく最近までジェネリック医薬品さえありませんでしたが、依然として重大な制限があります。これにより、コンポーネント モデルから Go へのコード生成がさまざまな点で複雑になります。

たとえば、次のような結果を生成できます<_ _>として:

type Result[V any] struct {
    value V
    err error
}

ただし、エラー位置に提供できる型が制限されます。したがって、次のようにコード生成する必要があります:

type Result[V any] struct {
    value V
    err error
}

これは機能しますが、他の慣用的な Go で使用すると面倒になります。Go では、上で定義した Result タイプと同じセマンティクスを示すために val, err := doSomething() 規則がよく使用されます。

さらに、この 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
}

これにより、型の安全性と不必要なラッピングのバランスが取れています。もちろん、ラッピングが必要な状況もありますが、それはエッジケースとして処理できます。

開発者は、非慣用的なパターンに苦労し、冗長で保守性の低いコードにつながる可能性があります。確立された規則を使用すると、コードがより親しみやすくなりますが、実装には追加の作業が必要になります。

コードベースを移動する際に何が起こるかを理解できるように、摩擦を最小限に抑え、チームにとって作業を容易にする慣用的な方法を採用することにしました。

呼び出し規約

ツール作成者が行う必要がある最大の決定の 1 つは、バインディングの呼び出し規約です。これには、インポートをいつどのようにコンパイルするか、Wasm モジュールをセットアップ中またはインスタンス化中、およびクリーンアップ中にコンパイルするかどうかの決定が含まれます。

Arcjet コードベースでは、パフォーマンスを最適化するためにファクトリ/インスタンス パターンを選択しました。 WebAssembly モジュールのコンパイルにはコストがかかるため、NewBotFactory() コンストラクターで 1 回だけ実行します。後続の Instantiate() 呼び出しは高速かつ安価であり、実稼働ワークロードでの高スループットが可能になります。

type BotConfig interface {
    isBotConfig()
}

func (AllowedBotConfig) isBotConfig() {}

func (DeniedBotConfig) isBotConfig() {}

消費者は NewBotFactory(ctx) を呼び出してこの BotFactory を 1 回構築し、それを使用して 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 を使用した後は、メモリ リークが発生していないことを確認するために、BotInstance をクリーンアップする必要があります。このために、Close 関数を提供します。

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

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 サービスのホット パス (レイテンシーが最も重要な場所) でのリクエスト処理が可能な限り効率的になるようにします。このトレードオフにより、初期化コードは多少複雑になりますが、リクエストごとのオーバーヘッドが大幅に減少するというメリットがあります。トレードオフについての説明を参照してください

トレードオフ

2 つ以上の言語を統合する必要がある場合は常に、ネイティブ FFI を使用する かコンポーネント モデルを使用するかにかかわらず、トレードオフを行う必要があります。

この投稿では、アークジェットで遭遇したいくつかの課題と、その決定の背後にある理由について説明しました。コンポーネント モデルや WIT などの同じプリミティブのセットを全員が構築すると、wit-bindgenwit-component などの高品質のプリミティブの同じセットを活用できます。 を使用して、あらゆるユースケースに適したツールを構築します。これが、標準に向けた取り組みがすべての人に役立つ理由です。

WebAssembly コンポーネント モデルは、言語間の統合のための強力な抽象化を提供しますが、その型を Go などの言語に変換すると、微妙な設計上の課題が生じます。ファクトリ/インスタンス パターンの使用など、慣用的なパターンを選択し、パフォーマンスを選択的に最適化することで、効率を維持しながら自然な開発者エクスペリエンスを提供できます。

コンポーネント モデルに関するツールが進化するにつれて、これらの統合をさらに簡素化する、より洗練されたコード生成アプローチが期待できます。

以上がWasm コンポーネント モデルと慣用的な codegenの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Golang:Goプログラミング言語が説明しましたGolang:Goプログラミング言語が説明しましたApr 10, 2025 am 11:18 AM

GOのコア機能には、ガベージコレクション、静的リンク、並行性サポートが含まれます。 1. GO言語の並行性モデルは、GoroutineとChannelを通じて効率的な同時プログラミングを実現します。 2.インターフェイスと多型は、インターフェイスメソッドを介して実装されているため、異なるタイプを統一された方法で処理できます。 3.基本的な使用法は、関数定義と呼び出しの効率を示しています。 4。高度な使用法では、スライスは動的なサイズ変更の強力な機能を提供します。 5.人種条件などの一般的なエラーは、Getest Raceを通じて検出および解決できます。 6.パフォーマンス最適化Sync.Poolを通じてオブジェクトを再利用して、ゴミ収集圧力を軽減します。

Golangの目的:効率的でスケーラブルなシステムの構築Golangの目的:効率的でスケーラブルなシステムの構築Apr 09, 2025 pm 05:17 PM

GO言語は、効率的でスケーラブルなシステムの構築においてうまく機能します。その利点には次のものがあります。1。高性能:マシンコードにコンパイルされ、速度速度が速い。 2。同時プログラミング:ゴルチンとチャネルを介してマルチタスクを簡素化します。 3。シンプルさ:簡潔な構文、学習コストとメンテナンスコストの削減。 4。クロスプラットフォーム:クロスプラットフォームのコンパイル、簡単な展開をサポートします。

SQLソートのステートメントによる順序の結果がランダムに見えるのはなぜですか?SQLソートのステートメントによる順序の結果がランダムに見えるのはなぜですか?Apr 02, 2025 pm 05:24 PM

SQLクエリの結果の並べ替えについて混乱しています。 SQLを学習する過程で、しばしば混乱する問題に遭遇します。最近、著者は「Mick-SQL Basics」を読んでいます...

テクノロジースタックの収束は、テクノロジースタック選択のプロセスにすぎませんか?テクノロジースタックの収束は、テクノロジースタック選択のプロセスにすぎませんか?Apr 02, 2025 pm 05:21 PM

テクノロジースタックの収束とテクノロジーの選択の関係ソフトウェア開発におけるテクノロジーの選択、テクノロジースタックの選択と管理は非常に重要な問題です。最近、一部の読者が提案しています...

反射比較を使用し、GOの3つの構造の違いを処理する方法は?反射比較を使用し、GOの3つの構造の違いを処理する方法は?Apr 02, 2025 pm 05:15 PM

GO言語で3つの構造を比較および処理する方法。 GOプログラミングでは、2つの構造の違いを比較し、これらの違いを...

Goでグローバルにインストールされたパッケージを表示する方法は?Goでグローバルにインストールされたパッケージを表示する方法は?Apr 02, 2025 pm 05:12 PM

Goでグローバルにインストールされたパッケージを表示する方法は? GO言語で開発する過程で、GOはしばしば使用します...

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか?Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか?Apr 02, 2025 pm 05:09 PM

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか?ゴーランドを使用するためにGolandを使用する場合、多くの開発者はカスタム構造タグに遭遇します...

See all articles

ホット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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい