AssemblyLift v0.2.9: BIG performance boost + new features! 🚀
Tags: rust, showdev, webassembly, serverless
Published: 2021-02-10 04:35:07

So many updates, so little time!

As usual I've been neglecting to write stuff down, but I've still been busy. :)

[AssemblyLift](https://assemblylift.akkoro.io) 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](https://wasmer.io) 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:
```rust
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:
```rust
// "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](https://github.com/akkoro/assemblylift/pull/33).

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](https://terraform.io) 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:
```bash
cargo install assemblylift-cli
```

Check out the [landing page](https://assemblylift.akkoro.io) for links to resources! Unfortunately, said resources are a tad scarce at the moment, but I assure you it's being worked on. 🙃

![A screenshot from the movie Clerks, in which Dante hangs the sign which reads "I assure you we're open"](https://dev-to-uploads.s3.amazonaws.com/i/namgx9nvr79gt5waz7k4.jpg)

Thanks for looking!