So many updates, so little time!
As usual I've been neglecting to write stuff down, but I've still been busy. :)
AssemblyLift has been quietly updated several times recently (mostly in December), iteratively adding features that I needed while building the IOmod registry infrastructure.
The most recent update, 0.2.9, was just published the other day and includes an upgrade to Wasmer 1.0 inside the AssemblyLift Lambda runtime. The latest build of Wasmer gives us significant gains, so I thought now would be a good time to document all the recent changes! 🎉
Changes for Rust guest code
Guest-facing changes were relatively minor, but offer a lot more flexibility on function input.
The only breaking change, introduced via 0.2.8, is a change which adds a type parameter to to LambdaContext
. This is the type of the incoming lambda event.
For a function invoked via HTTP for example:
handler!(context: LambdaContext<ApiGatewayEvent>, async {...})
The ApiGatewayEvent
struct itself also now deserializes the request_context
field, which gives access to authorization information (such as user ID), among other things.
For example:
// "sub" is the UUID of the authorized user
let user_id = event.request_context
.unwrap()
.authorizer
.unwrap()
.claims
.unwrap()
.get("sub")
.unwrap()
.to_string();
Changes to service & function definitions
Service TOML definitions now support specifying authorizers by ID for each function. These map to API Gateway authorizers; currently only IAM and JWT are supported. See the pull request for examples.
The fields timeout
and size
are now recognized optional parameters for function definition. Timeout refers to the function timeout in seconds; the duration after which the function will terminate. Size specifies the function size in megabytes, defaulting to 1024Mb.
Finally, it is now possible to include custom Terraform code in your AssemblyLift app. This code is placed in a directory which must be called user_tf
. This directory will be interpreted as a Terraform module and injected in the HCL code which is generated by asml
during cast
.
Changes to core & runtime
As mentioned, the big news here is the upgrade to Wasmer 1.0. Wasmer is the WebAssembly runtime AssemblyLift uses internally to execute compiled WASM code.
Internally there were many enhancements & fixes to the AssemblyLift runtime, which includes the removal of nearly all Rust code marked unsafe
! In particular the ABI code was simplified a bunch, with 447 additions and 848 deletions! 🙂
Pre-compiled WASM
Previously, WASM modules were loaded & compiled to native binary by Cranelift during Lambda initialization. For simple modules this wasn't so bad, but for real-world use the cold-start times (i.e. the time to start the Lambda runtime) were high -- around 1 second in my usage.
Wasmer 1.0 supports cross-compiling WASM to native binary and serializing the result, to be loaded later by the runtime. We use this in AssemblyLift, by adding this compilation step to asml cast
. After compiling Rust to WASM, asml
will invoke Cranelift and compile the WASM bytes to Amazon Linux-compatible binary. This brings our cold-start times down to around 200ms! I should disclaim though that this is an anecdotal benchmark; I'll need time to do something more formal.
Execution speed appears to be faster overall, though I will need to test this further as well. FWIW I can say that a function I have, which performs a batch-write to DynamoDB and then invokes another service function to perform a PUT to S3, has a warm execution time which is usually sub-300ms.
It is also possible, but not yet supported, to use LLVM in place of Cranelift. This should result even faster execution speed once we get it implemented!
Getting Started
If you're coming across AssemblyLift for the first time, you can install it via cargo with:
cargo install assemblylift-cli
Check out the landing page for links to resources! Unfortunately, said resources are a tad scarce at the moment, but I assure you it's being worked on. 🙃
Thanks for looking!
Top comments (0)