Slide 1

Slide 1 text

Turning CDN edge into a Rack web server with ruby.wasm Kay Sawada(@remore)

Slide 2

Slide 2 text

Introduction

Slide 3

Slide 3 text

WASI WebAssembly System Interface

Slide 4

Slide 4 text

Local computer [status, headers, body] Browser (JS engine) Wasm runtime Any workstation (local/server) Wasm runtime(WASI)

Slide 5

Slide 5 text

Demo (WASI)

Slide 6

Slide 6 text

Turning CDN edge into a Rack web server with ruby.wasm Kay Sawada(@remore)

Slide 7

Slide 7 text

CDN Edge?

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Source: github.com/kateinoigakukun/ruby-compute-runtime examples/demo.rb Demo: https://ruby-compute-runtime-demo.edgecompute.app/

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

🤔

Slide 12

Slide 12 text

Turning CDN edge into a Rack web server with ruby.wasm Kay Sawada(@remore)

Slide 13

Slide 13 text

Rack

Slide 14

Slide 14 text

Rack: A modular Ruby web server interface Rack provides a minimal, modular, and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it uni fi es and distills the bridge between web servers, web frameworks, and web application into a single method call. source: github.com/rack/rack/blob/main/README.md

Slide 15

Slide 15 text

Rack provides a minimal, modular, and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it uni fi es and distills the bridge between web servers, web frameworks, and web application into a single method call. source: github.com/rack/rack/blob/main/README.md

Slide 16

Slide 16 text

VPS ( Linux / 512MB / 20GB Disk) Http Client NGINX Unicorn Listen Connect Responding with Rack

Slide 17

Slide 17 text

VPS ( Linux / 512MB / 20GB Disk) Http Client NGINX Unicorn UNIX Socket Unicorn Listen Connect Sinatra App [status, headers, body]

Slide 18

Slide 18 text

$ cat config.ru run PersonalWebsite::App $ rackup

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

VPS ( Linux / 512MB / 20GB Disk) Http Client NGINX Unicorn UNIX Socket Unicorn Listen Connect Sinatra App [status, headers, body]

Slide 21

Slide 21 text

Http Client Sinatra App ruby.wasm running on top of CDN Edge [status, headers, body]

Slide 22

Slide 22 text

CDN Edge Http Client ruby.wasm (WASI) Hostcall (WASI Implementation) demo.rb Call

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

Lobster (Rack App) [status, headers, body] CDN Edge Http Client ruby.wasm (WASI) Hostcall (WASI Implementation) some_ruby_code_to_run_Rack_app.rb Call

Slide 26

Slide 26 text

Source: github.com/kateinoigakukun/ruby-compute-runtime examples/lobster.rb Demo: https://test-lobster.edgecompute.app/

Slide 27

Slide 27 text

What it takes to run a Rack App on WASI?

Slide 28

Slide 28 text

✅ HTTP Response body HTTP Request header HTTP Request body HTTP Response status code HTTP Response header

Slide 29

Slide 29 text

✅ HTTP Response body ⛔ HTTP Request header ⛔ HTTP Request body ⛔ HTTP Response status code ⛔ HTTP Response header

Slide 30

Slide 30 text

Add support for unsupported Hostcalls

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

✅ ✅

Slide 36

Slide 36 text

✅ ✅

Slide 37

Slide 37 text

CDN Edge Http Client ruby.wasm (WASI) Hostcall (WASI Implementation) some_ruby_code_to_run_Rack_app.rb Call Lobster (Rack App) [status, headers, body]

Slide 38

Slide 38 text

My Blog App?

Slide 39

Slide 39 text

class

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

â›” C Extention

Slide 42

Slide 42 text

✅

Slide 43

Slide 43 text

Sinatra::IndifferentHash::Gem (NameError) 2024-05-06T19:00:12.023137Z INFO request{id=0}: handling request GET http://localhost:7676/ /bundle/gems/sinatra-4.0.0/lib/sinatra/indifferent_hash.rb:189:in `': uninitialized constant Sinatra::IndifferentHash::Gem (NameError) from /bundle/gems/sinatra-4.0.0/lib/sinatra/indifferent_hash.rb:41:in `’ from /bundle/gems/sinatra-4.0.0/lib/sinatra/indifferent_hash.rb:3:in `’ from /bundle/gems/sinatra-4.0.0/lib/sinatra/base.rb:21:in `require’ from /bundle/gems/sinatra-4.0.0/lib/sinatra/base.rb:21:in `’ from /exe/blog/app.rb:1:in `require’ from /exe/blog/app.rb:1:in `’ from /exe/sinatra.rb:23:in `require’ from /exe/sinatra.rb:23:in `’ 2024-05-06T19:00:12.282052Z ERROR request{id=0}: WebAssembly exited with error: error while executing at wasm backtrace: 0: 0xaf237a - !__wasi_proc_exit 1: 0xa2c64a - !_start Caused by: Exited with i32 exit status 1

Slide 44

Slide 44 text

indifferent_hash.rb L189 â›” uninitialized constant

Slide 45

Slide 45 text

✅

Slide 46

Slide 46 text

â›” Need to adjust fi le path

Slide 47

Slide 47 text

✅ ✅ ✅

Slide 48

Slide 48 text

Sinatra Demo: https://distinctly-star-ant.edgecompute.app/

Slide 49

Slide 49 text

Experiments for other rack applications 🤔 tDiary runtime error: dependency to unsupported features (e.g. mkdir, socket etc. remember wasi-vfs is a read-only fi lesystem) 🤔 Rails build error: build doesn’t succeed out of the box
 (e.g. issue in installing bigdecimal) ✅ Rhino

Slide 50

Slide 50 text

What worked My Sinatra blog application works with CDN Edge environment if I; ✦ Added support to Compute Ruby SDK for unsupported host calls ✦ Adjusted fi le path to read blog contents from local fi lesystem

Slide 51

Slide 51 text

Challenges Static fi les are too big to add to wasi-vfs layer (<100MB wasm package size limit) Limited # of frameworks works out of the box ✦Limitations on fi le and network I/O etc Performance issue Gem with C Extension doesn’t work -> ✅ soon to be addressed🤞

Slide 52

Slide 52 text

Size & Performance File size Heap memory Avg. response time demo.wasm 35MB (with stdlib) 78MB 250ms lobster.wasm 35MB 79MB 300ms sinatra.wasm (my blog) *without images/js/css 38MB 88MB 1100ms roda.wasm 36MB 79MB 350ms

Slide 53

Slide 53 text

Bonus; Steps to build Compute Ruby SDK Ruby, Rust and wasi-preset-args are required $ apt update && apt upgrade $ apt-install rbenv libyaml-daev clang $ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build $ rbenv install 3.3.0 && rbenv global 3.3.0 $ ruby -v ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux] $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh && . “$HOME/.cargo/env" $ rustc —version rustc 1.77.1 (7cf61ebde 2024-03-27) $ cargo install --git https://github.com/kateinoigakukun/wasi-preset-args.git —all-features $ git clone https://github.com/kateinoigakukun/ruby-compute-runtime.git $ cd ruby-compute-runtime/examples $ bundle install # bump zlib version if needed by editing zlib.rb $ bundle exec ruby-compute-runtime demo.rb -o demo.wasm

Slide 54

Slide 54 text

Thanks!