Talks

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

RubyKaigi 2024

00:00:01.560 Hello everyone, welcome to the session. Thank you for joining.
00:00:06.279 I am Kay Sawada, and today I'm going to talk a little bit about Ruby and the area that I'm focusing on, which is the computing side.
00:00:10.920 I'll be discussing the WASI interface, so let's get started. First, let me give you a quick introduction.
00:00:19.760 I'll spend about half of this session doing a terminal demo, so I'll be switching my screen back and forth between this keynote and the terminal.
00:00:24.400 To start off, I've been working with Ruby since 2011. My goal here is to showcase my favorite gem, which I created about ten years ago.
00:00:36.360 At RubyKaigi 2014, I gave a presentation about this Ruby gem, and this will be my second time speaking at RubyKaigi. This revision is interesting as it demonstrates some unique game development frameworks.
00:00:46.600 As someone who worked for a gaming company, I developed this as a side project. By using a simple command, we can create a binary file that can be optimized for loading into a game.
00:01:04.920 The idea is that we can create a file that can be loaded and utilized for optimization. Maman started his project with this concept, and I feel honored to be here again.
00:01:12.720 This introduction may not relate directly to WebAssembly, but I believe that Uto has made interesting progress using WebAssembly for various projects in this environment.
00:01:29.520 Now, let's proceed to discuss WebAssembly and the WASI interface. Many of you may not be too familiar with the WebAssembly world yet.
00:01:41.200 WebAssembly can operate in two environments: one is within the browser, referred to as WASM, and the other is outside the browser, known as WASI.
00:02:03.400 Simply put, WebAssembly can run anywhere, and with the help of the WASI specification, it can also run outside the browser.
00:02:29.800 Yesterday, you may have seen a demo that covered WebAssembly working in the browser, but my focus today is how we can utilize it outside of that environment.
00:02:35.760 The title of my talk is 'Turning CDN Edge into a Rack Web Server with Ruby'. First, let me define what a CDN edge is, as you may not be familiar with it.
00:02:53.360 A CDN, or Content Delivery Network, is often seen as a platform to download static content. However, it can also offer functionalities beyond that.
00:03:04.360 For example, when downloading gems, we usually communicate with the RubyGems.org website, which is hosted on a CDN.
00:03:19.959 This CDN consists of multiple points of presence (POPs) located around the world, enabling efficient content delivery.
00:03:30.000 With the addition of WebAssembly support, you can run your programs directly on these CDN networks. This means you can deploy arbitrary applications across the multitude of POPs globally.
00:03:49.600 Currently, my company, Fastly, supports languages such as Go and JavaScript while Ruby is unofficially in development.
00:04:04.760 Two years ago, Uto delivered a keynote at RubyKaigi where he created an initial version of a project related to WebAssembly, which sparked my interest in what could be achieved with Ruby in this environment.
00:04:19.160 With the evolution of this concept, I've been curious about the possibility of running a Rack web server on CDN edge locations.
00:04:36.560 Most of us are likely familiar with Rack, the Ruby web server interface, and there are many frameworks built on top of it, like Rails or Sinatra.
00:04:53.319 My thought was to create a solution to help migrate Ruby applications onto the edge network without significant changes to existing code.
00:05:09.519 Here's an overview of the setup I used. I've been hosting this since 2015, utilizing a simple VPS instance to run an NGINX server with Unicorn for my blog application.
00:05:22.960 The aim here is to determine the feasibility of transforming my blog application into a CDNH, and to explore the basic components of this architecture.
00:05:36.000 The key concept is to implement a middleware that allows my Rack application to interface seamlessly with the CDN edge.
00:05:51.599 In this architecture, I've realized that some adaptations would be necessary, despite my initial intention of running my existing applications unchanged.
00:06:04.160 Starting with a reference implementation called 'Lobster,' I confirmed that it successfully runs on the edge network.
00:06:18.400 This implementation ensures that basic functionalities work correctly and can flip between states when executed on a CDN.
00:06:34.759 Next, I wanted to detail how I made this happen, adjusting various pieces beyond the initial example to enhance functionality.
00:06:54.639 This involved reviewing the existing code for required functionalities such as request header manipulation and response handling, necessitating the addition of new modules.
00:07:04.959 At that point, I found the need to create some Ruby C extensions to polish these responses and handle the outgoing requests properly.
00:07:19.040 The resulting code was light, allowing me to interface successfully with my Rack components and obtain headers as expected.
00:07:36.679 While my setup worked in many aspects, migrating to the CDN edge presented challenges, particularly with missing extensions.
00:07:46.679 While inspected, I discovered that I couldn't utilize C extensions and had to find an alternative library written purely in Ruby.
00:08:00.679 I addressed some missing constant issues by adjusting a line of code in my gemfile, while also modifying some path definitions to work effectively.
00:08:17.239 Ultimately, I managed to make the application function, although the static content was not bundled in the WebAssembly binary due to size limitations.
00:08:32.159 Moving forward, applications such as Sinatra shows promise, while other Ruby applications like TDiary encountered issues during runtime.
00:08:50.159 While Sinatra works, the TDiary application faced internal errors related to file system limitations imposed by the WebAssembly environment.
00:09:09.519 Additionally, Rails applications also showed challenges, particularly with decimal data types which need careful adjustments to run.
00:09:22.919 While some applications function seamlessly, others like Rhino perform adequately, indicating varying levels of compatibility.
00:09:38.959 To sum up my findings, my blog application worked with modifications, revealing challenges in various implementation scenarios and migration processes.
00:09:56.560 Key obstacles included large static file sizes exceeding the limits of WebAssembly binaries, along with a limited number of frameworks that support operations out of the box.
00:10:14.480 Performance issues also arose, as evidenced by longer load times for certain Ruby frameworks in comparison to others supported by the edge network.
00:10:32.400 Determining accurate response times revealed that applications like Sinatra took over a second to respond on average.
00:10:37.760 By contrast, simpler applications using Go frameworks exhibited faster response times under 100 milliseconds, further highlighting these performance disparities.
00:11:02.560 Engaging with the terminal and testing the applications further clarified the points discussed, establishing a clearer view of the challenges faced.
00:11:19.360 Looking ahead, I'll explore the current state of the Ruby WebAssembly projects and their evolving opportunities while addressing improvement areas.
00:11:40.239 Ruby presents great potential in edge computing environments, and I'd encourage you all to dive into the Ruby WebAssembly GitHub repository to discover valuable insights.
00:12:01.440 Thank you all for your attention, and let’s work together to make Ruby more engaging and exciting in the WASM world.
00:12:20.440 Thank you so much for coming, and let's continue this conversation. Your thoughts and feedback are invaluable as we strive to enhance our journey into this exciting domain.