mirror of
https://github.com/extism/extism.git
synced 2026-04-23 03:00:11 -04:00
EIP: https://github.com/extism/proposals/pull/8 This PR makes minor breaking changes to several SDKs, but not to runtime C API. The threadsafety updates in the Rust SDK are kind of specific to Rust, I'm not sure if it makes sense to add the locks to all the other SDKs at this point. For the most part the `Context` and `Plugin` types in the SDKs should be safe to use protected by a mutex but they aren't inherently threadsafe. That kind of locking should probably be done by the user. - Runtime - improve thread safety - reinstantiates less - fixes a potential resource exhaustion bug from re-instantiating using the same store too many times - Rust SDK - adds `Send` and `Sync` implementations for `Context` - adds test sharing a context between threads - adds `Plugin::call_map` to call a plugin and handle the output with the lock held - adds testing sharing an `Arc<Mutex<Plugin>>` between threads - adds `Plugin::create` and `Plugin::create_from_manifest` to create a plugin without a `Context` - Python - BREAKING - changes `Plugin` constructor to take `context` as an optional named argument, to update use `Plugin(data, context=context)` instead - Ruby - BREAKING - changes `Plugin` constructor to take `context` as an optional named argument, to update use `Plugin.new(data, context=context)` instead - Go - adds `NewPlugin` and `NewPluginFromManifest` functions - Node - BREAKING - changes `Plugin` constructor to take `context` as an optional named argument, to update use `new Plugin(data, wasi, config, host, context)` instead of `new Plugin(context, data, wasi, functions, config)` (most people are probably using `context.plugin` instead of the Plugin constructor anyway) - OCaml - BREAKING - changes `Plugin.create` and `Plugin.of_manifest` to take `context` as an optional named argument, to update `Plugin.create ~context data` and `Plugin.of_manifest ~context data` instead - Haskell - adds `createPlugin` and `createPluginFromManifest` functions - Elixir - adds `Plugin.new` to make a plugin without going through `Context.new_plugin` - Java - adds new `Plugin` constructors without a `Context` argument - C++ - BREAKING - Updates `Plugin` constructor to take an optional context as the last argument, instead of requiring it to be the first argument - Use `Plugin(wasm, wasi, functions, ctx)` instead of `Plugin(ctx, wasm, wasi, functions)` - Zig - Adds `Plugin.create` and `Plugin.createWithManifest` to create plugins in their own context. --------- Co-authored-by: zach <zach@dylib.so> Co-authored-by: Benjamin Eckel <bhelx@simst.im>
Extism
Extism Host SDK for Elixir and Erlang
Docs
Read the docs on hexdocs.pm.
Installation
You can find this package on hex.pm.
def deps do
[
{:extism, "~> 0.1.0"}
]
end
Getting Started
Example
# Create a context for which plugins can be allocated and cleaned
ctx = Extism.Context.new()
# point to some wasm code, this is the count_vowels example that ships with extism
manifest = %{ wasm: [ %{ path: "/Users/ben/code/extism/wasm/code.wasm" } ]}
{:ok, plugin} = Extism.Context.new_plugin(ctx, manifest, false)
# {:ok,
# %Extism.Plugin{
# resource: 0,
# reference: #Reference<0.520418104.1263009793.80956>
# }}
{:ok, output} = Extism.Plugin.call(plugin, "count_vowels", "this is a test")
# {:ok, "{\"count\": 4}"}
{:ok, result} = JSON.decode(output)
# {:ok, %{"count" => 4}}
# free up the context and any plugins we allocated
Extism.Context.free(ctx)
Modules
The two primary modules you should learn are:
Context
The Context can be thought of as a session. You need a context to interact with the Extism runtime. The context holds your plugins and when you free the context, it frees your plugins. It's important to free up your context and plugins when you are done with them.
ctx = Extism.Context.new()
# frees all the plugins
Extism.Context.reset(ctx)
# frees the context and all its plugins
Extism.Context.free(ctx)
Plugin
The Plugin represents an instance of your WASM program from the given manifest. The key method to know here is Extism.Plugin#call which takes a function name to invoke and some input data, and returns the results from the plugin.
{:ok, plugin} = Extism.Context.new_plugin(ctx, manifest, false)
{:ok, output} = Extism.Plugin.call(plugin, "count_vowels", "this is a test")