Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Turning CDN edge into a Rack web server with ruby.wasm

Turning CDN edge into a Rack web server with ruby.wasm

Slides for my talk at RubyKaigi 2024;
https://rubykaigi.org/2024/presentations/remore.html

remore

May 17, 2024
Tweet

More Decks by remore

Other Decks in Technology

Transcript

  1. Local computer [status, headers, body] Browser (JS engine) Wasm runtime

    Any workstation (local/server) Wasm runtime(WASI)
  2. 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
  3. 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
  4. VPS ( Linux / 512MB / 20GB Disk) Http Client

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

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

    NGINX Unicorn UNIX Socket Unicorn Listen Connect Sinatra App [status, headers, body]
  7. 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
  8. ✅ HTTP Response body HTTP Request header HTTP Request body

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

    Request body ⛔ HTTP Response status code ⛔ HTTP Response header
  10. 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

    `<class:IndifferentHash>': uninitialized constant Sinatra::IndifferentHash::Gem (NameError) from /bundle/gems/sinatra-4.0.0/lib/sinatra/indifferent_hash.rb:41:in `<module:Sinatra>’ from /bundle/gems/sinatra-4.0.0/lib/sinatra/indifferent_hash.rb:3:in `<top (required)>’ 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 `<top (required)>’ from /exe/blog/app.rb:1:in `require’ from /exe/blog/app.rb:1:in `<top (required)>’ from /exe/sinatra.rb:23:in `require’ from /exe/sinatra.rb:23:in `<main>’ 2024-05-06T19:00:12.282052Z ERROR request{id=0}: WebAssembly exited with error: error while executing at wasm backtrace: 0: 0xaf237a - <unknown>!__wasi_proc_exit 1: 0xa2c64a - <unknown>!_start Caused by: Exited with i32 exit status 1
  11. 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
  12. 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
  13. 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🤞
  14. 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
  15. 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