WebAssembly on the Edge: Sandboxing AND Performance

ScyllaDB 170 views 29 slides Oct 14, 2024
Slide 1
Slide 1 of 29
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29

About This Presentation

Moving apps to the Edge can complicate performance due to security constraints. Learn how WebAssembly bridges the gap, enabling both speed and security. We'll share insights from Exograph app migrations, focusing on Wasi advancements and the new component model. #EdgeComputing #WebAssembly


Slide Content

A ScyllaDB Community
WebAssembly on the Edge:
Sandboxing AND Performance
Brian Sletten
Bosatsu Consulting, Inc.

Ramnivas Laddad
Exograph, Inc.

Brian Sletten (he/him)

President, Bosatsu Consulting, Inc
■Author of O'Reilly book "WebAssembly : The Definitive Guide"
■Author of "Resource-Oriented Architecture Patterns for Webs of
Data"
■Teaches and speaks internationally about REST, Semantic Web,
WebAssembly, Data Science, Machine Learning, GPU Computing,
Security, Visualization, Architecture
■International Pop Recording Artist

Ramnivas Laddad (he/him)

Co-founder, Exograph, Inc
■Former Spring Framework and Cloud Foundry
committer
■Author of “AspectJ in Action”
■Speaker at many professional conferences
■Indian Classical Music aficionado

WebAssembly

https://hacks.mozilla.org/2018/10/webassemblys-post-mvp-future

Edge Computing

https://tinyurl.com/edge-landscape

Exograph

Express the domain model
and have the server ready! ??????
context AuthContext {
@jwt("sub") id: Int
@jwt role: String
}

@postgres
module ConcertData {
type Concert {
@pk id: Int = autoIncrement()
title: String
venue: Venue
}

@access(AuthContext.role == "ADMIN")
type Venue {
@pk id: Int = autoIncrement()
name: String
concerts: Set<Concert>
published: Boolean
}
}

Exograph
Builder
exo_ir
Exograph
Runtime
context AuthContext {
@jwt("sub") id: Int
@jwt role: String
}

@postgres
module ConcertData {
type Concert {
@pk id: Int = autoIncrement()
title: String
venue: Venue
}

@access(AuthContext.role == "ADMIN")
type Venue {
@pk id: Int = autoIncrement()
name: String
concerts: Set<Concert>
published: Boolean
}
}

{
concerts {
id
title
}
}

{
"data": {
"concerts": [
{
"id": 1,
"title": “The Beatles"
},
{
"id": 2,
"title": "The Rolling Stones"
}
]
}
}

Exograph Deployment Targets

Demo

Moving to the Edge

Experience post Rust code: Computation
■Serializing intermediate representation to/from its model
■Parsing and validating GraphQL queries
■Mapping GraphQL queries to SQL
■Validating JWT tokens

Experience post Rust code: System Interface
#[cfg(not(target_family = "wasm"))]
use std::time::Instant;
#[cfg(target_family = "wasm")]
use web_time::Instant;

Connecting to Postgres
let socket = Socket::builder()
.secure_transport(SecureTransport::StartTls)
.connect(host, port)?;

wasm_bindgen_futures::spawn_local(async move {
if let Err(error) = pg_connection.await {
// report
}
});
let (pg_client, pg_connection) = config
.connect_raw(socket, PassthroughTls)
.await?;

Contributing back to the ecosystem
■rust-postgres
●A new API to make it work with external pooling
■oidc-jwt-validator
●Async runtime adjustment
●std::time replacement
■tree-sitter-c2rust
■worker-rs
■deadpool-postgres

Challenges

Latency in Module Loading

Exograph
Builder
exo_ir
Exograph
Runtime
context AuthContext {
@jwt("sub") id: Int
@jwt role: String
}

@postgres
module ConcertData {
type Concert {
@pk id: Int = autoIncrement()
title: String
venue: Venue
}
@access(AuthContext.role == "ADMIN")
type Venue {
@pk id: Int = autoIncrement()
name: String
concerts: Set<Concert>
published: Boolean
}
}

{
concerts {
id
title
}
}

{
"data": {
"concerts": [
{
"id": 1,
"title": “The Beatles"
},
{
"id": 2,
"title": "The Rolling Stones"
}
]
}
}

Exograph
Builder
exo_ir
Exograph
Runtime
context AuthContext {
@jwt("sub") id: Int
@jwt role: String
}

@postgres
module ConcertData {
type Concert {
@pk id: Int = autoIncrement()
title: String
venue: Venue
}
@access(AuthContext.role == "ADMIN")
type Venue {
@pk id: Int = autoIncrement()
name: String
concerts: Set<Concert>
published: Boolean
}
}

{
concerts {
id
title
}
}

{
"data": {
"concerts": [
{
"id": 1,
"title": “The Beatles"
},
{
"id": 2,
"title": "The Rolling Stones"
}
]
}
}

Lowering Module Size: Do less work
■Simplify resolver logic
●Supported pre-defined queries (persisted/trusted queries)
●Map instead of compute
■Look up the query
■Find the query plan
■Validate variables
■Execute!
■Guide users in defining queries that can be mapped

Lowering Module Size: Tools
■wasm-opt, wasm-gc to optimize the size and DCE
■https://wasmphobia.surma.technology/ to analyze size contributions

Connection Latency: Application-level pooling
Exograph
Runtime
Pool
Exograph
Runtime
Pool
Error: Cannot perform I/O on behalf of a different request. I/O objects
(such as streams, request/response bodies, and others) created in the
context of one request handler cannot be accessed from a different
request's handler. This is a limitation of Cloudflare Workers which allows
us to improve overall performance. (I/O type: WritableStreamSink)

Connection Latency: Edge-provided pooling
Exograph
Runtime
Exograph
Runtime
Hyper
drive
No pooling: ~345ms
With Hyperdrive: ~60ms

Wasi

https://wasi.dev

https://wasi.dev/interfaces

Thank you! Let’s connect.
Brian Sletten
[email protected]
https://bosatsu.net
@[email protected]
Ramnivas Laddad
[email protected]
https://exograph.dev
@ramnivas
Tags