<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marius Kluften</title>
    <description>The latest articles on DEV Community by Marius Kluften (@brehen).</description>
    <link>https://dev.to/brehen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F259738%2F124bf6b0-de60-4e06-9b64-a9043bc8ef86.jpeg</url>
      <title>DEV Community: Marius Kluften</title>
      <link>https://dev.to/brehen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brehen"/>
    <language>en</language>
    <item>
      <title>Building Nebula - Chapter 2: Let's write some Wasm/Wasi modules with Rust</title>
      <dc:creator>Marius Kluften</dc:creator>
      <pubDate>Wed, 03 Jan 2024 12:12:43 +0000</pubDate>
      <link>https://dev.to/brehen/building-nebula-chapter-2-lets-write-some-wasmwasi-modules-leb</link>
      <guid>https://dev.to/brehen/building-nebula-chapter-2-lets-write-some-wasmwasi-modules-leb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Starting to interact with WebAssembly modules&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Some basic terminology
&lt;/h2&gt;

&lt;p&gt;In my previous two posts I laid out about why and how I'm building a Rust webserver that can spin up WebAssembly modules on request.&lt;/p&gt;

&lt;p&gt;You might be wondering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Isn't this essentially a web server that spins up the wasmtime runtime in the background? Is that a Serverless Faas Platform? 🤔&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;... 👀&lt;/p&gt;

&lt;p&gt;Yes. Yes, that is what I'm making. And I'm not 100% sure if the terminology matches, but I asked ChatGPT and I'm pretty happy with the answer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkc0n2egszkr5p975dooj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkc0n2egszkr5p975dooj.png" alt="Excerpt from a conversation with ChatGPT where I asked if Nebula could be described as a FaaS Platform. ChatGPT agrees that the project could fit the category." width="800" height="777"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we've ensured that what I'm trying to build could be called a "FaaS Platform", even though it is a bit limited, without auto-scaling, monitoring, logging and more. For the sake of experimentation, some of these features could be implemented in some shape or form. &lt;/p&gt;

&lt;p&gt;The dream feature is to be able to log power consumption readings from the server during each function call, and attempt to measure the "footprint" for each function, but we'll see how far Nebula evolves before the deadline in May.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Hey, what even are Wasm/Wasi modules?"
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7pta6rplypql70wrhc7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7pta6rplypql70wrhc7s.png" alt="Wait a minute, who are you meme kid looking at the Wasm Logo" width="500" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great question!&lt;/p&gt;

&lt;p&gt;Previously I've been focusing more on the "why" and "how" of using Wasm modules in Nebula, emphasising on their quick startup times and compact sizes. What remains&lt;br&gt;
is to delve into the nature of WebAssembly modules themselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebAssembly&lt;/strong&gt;, or &lt;strong&gt;Wasm&lt;/strong&gt; for short, is akin to a universal language for computer programs. Imagine you wrote down a recipe in such a way that anyone in the world could understand and cook it without needing a translator. That is what I imagine Wasm modules to be for code. It allows programs to run virtually everywhere, and even though it was first designed for the browser, its design enabled it to be a perfect fit for servers as well.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wasm was designed to run sandboxed in a browser, so how can we run it on the server?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is where the &lt;strong&gt;WebAssembly System Interface&lt;/strong&gt;, or &lt;strong&gt;Wasi&lt;/strong&gt;, comes in into play. Wasi is a project that is built to package our Wasm code in such a way that it can interface with an underlying system, and this is what enables us to run Wasm on our servers and allow us to do server specific tasks.&lt;/p&gt;

&lt;p&gt;In the context of Nebula, Wasm/Wasi modules are these recipes, ready to be whipped up and served in an instant on our server!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4sbr6j83g4v5j4usatu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4sbr6j83g4v5j4usatu.png" alt="An illustration of an AI generated Shiba Inu chef cooking with WebAssembly, Rust and Wasi spices, cooking Nebula." width="500" height="447"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Some actual code
&lt;/h2&gt;

&lt;p&gt;In the previous chapter, I concluded with a simple "Hello Simen" web page. It didn't even render HTML properly!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94y7fyrdxy28ccxaf2wx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94y7fyrdxy28ccxaf2wx.png" alt='First "HTML" version, which the browser interprets as clear text, and not actual HTML.' width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's dive deeper into the world of compiling Rust code into Wasi modules, which we will then run on Wasmtime. We'll start by coding our first function!&lt;br&gt;
Given my academic backdrop for this prototype, I'll begin with a well known computational challenge: the Fibonacci sequence.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Fibonacci?
&lt;/h3&gt;

&lt;p&gt;The Fibonacci sequence is a classic in computer science, where each number is the sum of the two preceding ones. Starting with 0 and 1, the sequence unfolds as 0, 1, 1, 2, 3, 5, 8, and so forth. While I haven't found a practical use for this during my career, it serves as a nice starting function for future benchmarking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6hjsr30yz4fbegm4b802.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6hjsr30yz4fbegm4b802.png" alt="Neko clothed in an outfit Fibonacci could have worn." width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Nice sequence, bro&lt;/em&gt;                             &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's my Rust code for generating the Fibonacci sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/main.rs&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// Create a vector (dynamically sized array-ish) to hold sequence&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// First two numbers equal their index&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Calculate next number in sequence and push to vector&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;next_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// println!("Help me");&lt;/span&gt;

    &lt;span class="c1"&gt;// Implicitly return the sequence&lt;/span&gt;
    &lt;span class="n"&gt;sequence&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Print out the returned value from the function in the main function, the entry point to Rust programs&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The first 5 fibonacci numbers are: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
  &lt;a href="https://github.com/brehen/nebula/blob/v0.2/functions/fibonacci/src/main.rs"&gt;
    [Source]
  &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Once we build this with wasm32-wasi as the target, we get a Wasi binary file that we can deploy and run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cargo build &lt;span class="nt"&gt;--target&lt;/span&gt; wasm32-wasi &lt;span class="nt"&gt;--release&lt;/span&gt;

    Compiling fibonacci v0.1.0 &lt;span class="o"&gt;(&lt;/span&gt;~/nebula/functions/fibonacci&lt;span class="o"&gt;)&lt;/span&gt;
      Finished release &lt;span class="o"&gt;[&lt;/span&gt;optimized] target&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;1.07s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we can execute it using the Wasmtime CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;wasmtime ./target/wasm32-wasi/release/fibonacci.wasm

    The first 5 fibonacci numbers are: &lt;span class="o"&gt;[&lt;/span&gt;0, 1, 1, 2, 3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty sweet! But as you might have noticed, I added a main function in my main.rs file where I called the function inside a println macro call. That's not very "FaaS platformy-esque", the users would normally expect to be able to provide their own input and get something out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling Input/Output with Wasi
&lt;/h2&gt;

&lt;p&gt;I wanted to build my Wasi-runner library code to be as generic as possible, where I could simply provide the name of the function, which would then result in Nebula looking up if it has the corresponding module binary file present, take in the input, run the function and return the output.&lt;/p&gt;

&lt;p&gt;I'm currently a level 2 newbie in the Rust ecosystem, with most of my skill points previously allotted to technologies related to JavaScript, like TypeScript, React and Node. This shift presented some challenges to me: building library code that allows me to generically craft Wasi modules, aligned with Rust's idiomatic practices, was quite an adventure. &lt;/p&gt;

&lt;p&gt;During this journey I crossed paths with Peter Malmgren's blog, where he had written an article: "Getting data in and out of WASI modules" (&lt;a href="https://petermalmgren.com/serverside-wasm-data/"&gt;link here&lt;/a&gt;). His insights, in which he laid out two different approaches to how you could achieve this back in 2022, proved to be invaluable. After experimenting, I found his first method, in which he relies on stdin and stdout for input and output respectively, to be particularly effective for my use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Treating WASI like a regular program
&lt;/h3&gt;

&lt;p&gt;Because WASI was designed to be POSIX-like, it has access to resources like standard input and output, CLI &lt;br&gt;
arguments, environment variables, pipes and network sockets. Peter explains it better than me, in his article, so if you're interested I would recommend checking it out.&lt;/p&gt;

&lt;p&gt;This mindset shifted my thinking around how I could solve this input/output issue. And while there might be more idiomatic ways to solve it, I ended up relying on stdin and stdout for my examples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import stdin and "attach" BufRead to the program&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BufRead&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create stdin instance&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Wait for data to be passed to stdin&lt;/span&gt;
    &lt;span class="n"&gt;stdin&lt;/span&gt;
        &lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.read_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to read line"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Attempt to parse it&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;parsed_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Pattern match on the input. Default to 1 if the stdin was invalid &lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed_input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// Calculate the sequence and print it to stdout&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;next_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// println!("Help me");&lt;/span&gt;

    &lt;span class="n"&gt;sequence&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, I await the input from stdin before the program goes further than line #7. Then I attempt to parse it to an u32 integer, if successful it will move on and pass the input to the fibonacci function. If it receives something other than a value that can be parsed to u32, it will default to 1, in order to simplify error handling.&lt;/p&gt;

&lt;p&gt;If we build this again, it still compiles and compiles to a &lt;strong&gt;.wasm&lt;/strong&gt; module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cargo build &lt;span class="nt"&gt;--target&lt;/span&gt; wasm32-wasi &lt;span class="nt"&gt;--release&lt;/span&gt;
    Compiling fibonacci v0.1.0 &lt;span class="o"&gt;(&lt;/span&gt;~/nebula/functions/fibonacci&lt;span class="o"&gt;)&lt;/span&gt;
      Finished release &lt;span class="o"&gt;[&lt;/span&gt;optimized] target&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;0.53s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can pipe in our input as stdin and receive our output like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo &lt;/span&gt;10 | wasmtime ./target/wasm32-wasi/release/fibonacci.wasm &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.txt
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;out.txt
  &lt;span class="o"&gt;[&lt;/span&gt;0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool! Now we're able to pass input to our Wasi module, and get output back! I realise that relying on side effects such as reading stdin and stdout might take&lt;br&gt;
a hit on performance, but I have taken the same approach to providing input and receiving output to the same functions wrapped in Docker images as well, in order to fairly compare the two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing words
&lt;/h2&gt;

&lt;p&gt;If you're interested in seeing how the project was at the end of this blog post, I have tagged it as version v0.2 in my GitHub repo (&lt;a href="https://github.com/brehen/nebula/tree/v0.2"&gt;Link here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The Fibonacci example lives under the folder functions/fibonacci.&lt;/p&gt;

&lt;p&gt;So, how can we expand on this way to interact with WebAssembly compiled Rust programs and expose them as functions for users of Nebula to call?&lt;/p&gt;

&lt;p&gt;In the next chapter we'll look at adding the Wasmtime crate to the project and transform our "Hello Simen" web-server into a fully fledged FaaS!*&lt;/p&gt;

&lt;p&gt;Stay tuned for &lt;a href="https://dev.to/blog/nebula_chapter3"&gt;Chapter 3&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;**&lt;em&gt;It will not be fully fledged for a good while, and I'm not sure if it ever&lt;br&gt;
will.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>serverless</category>
      <category>webassembly</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building Nebula - Chapter 1: Building a Prototype with Rust</title>
      <dc:creator>Marius Kluften</dc:creator>
      <pubDate>Tue, 07 Nov 2023 10:37:52 +0000</pubDate>
      <link>https://dev.to/brehen/building-nebula-chapter-1-building-a-prototype-with-rust-1iin</link>
      <guid>https://dev.to/brehen/building-nebula-chapter-1-building-a-prototype-with-rust-1iin</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The beauty of Rust and WebAssembly as the pillars for a new wave of Cloud computing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the previous post, I laid out my motivations for Nebula - a FaaS prototype designed to explore the power of WebAssembly. &lt;/p&gt;

&lt;p&gt;In this post we'll start diving into the "how".&lt;/p&gt;

&lt;h2&gt;
  
  
  A journey beyond JavaScript
&lt;/h2&gt;

&lt;p&gt;The first 4 years of my career was dedicated to mastering the JavaScript ecosystem, where my primary quest was to enhance the user experience of every interface I developed. There's no doubt; JavaScript, with its ubiquity, will likely dominate the web space for many years. However, an encounter with the 2nd edition of &lt;a href="https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/"&gt;The Pragmatic Programmer&lt;/a&gt; in 2020 nudged me in a fresh direction.&lt;/p&gt;

&lt;p&gt;The book's tip #9, &lt;strong&gt;"Invest regularly in your knowledge portfolio"&lt;/strong&gt;, struck a chord. While the author advocated learning a new programming language annually, I ended up choosing depth over breadth, immersing myself in the world of functional programming through Elixir from 2020 to 2022.&lt;/p&gt;

&lt;p&gt;But 2023? I decided to start a new side quest and discover what the 🦀 hype was all about. The video &lt;a href="https://www.youtube.com/watch?v=0rJ94rbdteE"&gt;Rust makes you feel like a GENIUS&lt;/a&gt; by No Boilerplate sealed the deal. &lt;/p&gt;

&lt;p&gt;I was, as no one surely says, &lt;em&gt;"crab trapped"&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rust: More than just hype
&lt;/h2&gt;

&lt;p&gt;My years navigating the vast sea of JavaScript have been both rewarding and challenging. The language, while very flexible, can occasionally feel like assembling a jigsaw puzzle with ever-changing pieces.&lt;/p&gt;

&lt;p&gt;TypeScript improves this story by leaps and bounds in my day job, but for building Nebula - a prototype designed to swiftly spin up WebAssembly modules - I needed a more efficient and predictable environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is Rust great for the Nebula journey
&lt;/h3&gt;

&lt;p&gt;Beyond my own personal reasons for wanting to explore Rust, I have compiled some of my reasons for choosing Rust.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Safety First:&lt;/strong&gt; Rust's strict compiler and ownership model ensures that code I write for my prototype is less prone to common bugs, memory leaks and data races. These features will hopefully act as safety rails for developing my prototype.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency and Reproducibility:&lt;/strong&gt; For my research I need reliable reproducibility. With its predictable performance, I should be able to gather better data to compare later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamlined Efficiency:&lt;/strong&gt; My thesis requires a playground to rapidly iterate and experiment on. Rust's powerful concurrency model and zero-cost abstractions allow me to refine the logic of my prototype without worrying about performance bottlenecks. (Famous last words?)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A great WebAssembly story:&lt;/strong&gt; WebAssembly has been a first class citizen in the Rust ecosystem for a considerable time. Furthermore Fermyon - the company that inspired my thesis - places substantial trust in Rust for their platform and SDK.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Building the first iteration
&lt;/h2&gt;

&lt;p&gt;While the focus for my project is on building with Rust and run WebAssembly modules as functions, the road to getting there includes many steps. As of writing this, I already have a simple prototype working, and I'll try to lay out my journey to landing there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing the WebAssembly Runtime
&lt;/h3&gt;

&lt;p&gt;For running Wasm modules on the platform, it's crucial to have a reliable WebAssembly runtime. There's a plethora of options available: Wasmer, Wasmo, Wasmi, WasmEdge, and Wasmtime to name a few. My research led me to notice that Fermyon had opted for Wasmtime. After a deep dive into Wasmtime, I was impressed by their well-documented Rust crate, allowing me to effortlessly integrate Wasmtime into my Rust project. A pleasant surprise was realizing that the final binary build didn't necessitate having the wasmtime runtime installed on my server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Designing the Web Server Infrastructure
&lt;/h3&gt;

&lt;p&gt;While the choice of WebAssembly runtime was crucial, the actual mechanism to serve and interact with these modules was equally vital. How do industry giants do it? Amazon with their Lambda, Google with Cloud Functions, or Microsoft with Azure Functions? Without the exact blueprint, I decided on crafting a feasible solution for my experimentation: a web server using Rust and Axum.&lt;/p&gt;

&lt;p&gt;The backbone of this server includes a shared crate library. This library acts as the bridge between the web server and the Wasmtime runtime. The envisioned workflow is simple:&lt;/p&gt;

&lt;p&gt;In my sketch below, I've drawn up a rough idea of what I want the platform to do in the first iteration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BZRwyWM8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/329zkw4nzuxwaqv8o00m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BZRwyWM8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/329zkw4nzuxwaqv8o00m.png" alt="Rough sketch of the first iteration" width="800" height="668"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User A calls the API (most likely REST API) with GET /api/treats/10 (/api/:module/:input)&lt;/li&gt;
&lt;li&gt;Axum web server receives request, finds the corresponding wasm module "deployed" to the server from the module name, creates a wasmtime instance and provides it with the input.&lt;/li&gt;
&lt;li&gt;The wasm module runs the function based on provided input and returns the output as a valid Wasm type. (In this case i32)&lt;/li&gt;
&lt;li&gt;The web server responds the user with the value returned from the wasm module.&lt;/li&gt;
&lt;li&gt;????&lt;/li&gt;
&lt;li&gt;Neko is a happy dog, because he got 10 treats at (hopefully) BLAZINGLY fast startup speeds!&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Humble beginnings
&lt;/h3&gt;

&lt;p&gt;My main.rs file looked like this in my first iteration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;IpAddr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;routing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"
              &amp;lt;!DOCTYPE html&amp;gt;
              &amp;lt;html&amp;gt;
                &amp;lt;body&amp;gt;
                  &amp;lt;div&amp;gt;
                    Hei Simen!&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Hvordan går det? :)
                  &amp;lt;/div&amp;gt;
                &amp;lt;/body&amp;gt;
              &amp;lt;/html&amp;gt;"&lt;/span&gt; 
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// run it with hyper on localhost:3000&lt;/span&gt;
    &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8080"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;.serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="nf"&gt;.into_make_service&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The root page now looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0ZIrudVn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lc354y6ulv15ccth8tok.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0ZIrudVn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lc354y6ulv15ccth8tok.jpg" alt="First iteration" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While maybe not an technically impressive web page, and I'd expect more from my self after 6 years of web development, I still had managed to get a web server in something other than Node and Express up and running!&lt;/p&gt;

&lt;p&gt;Smells like victory!&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing words
&lt;/h2&gt;

&lt;p&gt;Now you might be wondering: "Wait. What happened with steps 2 through 6? Neko ain't getting no treats with this rudimentary Hello World web server?? What gives??".&lt;/p&gt;

&lt;p&gt;Great question! We'll explore that further in the next chapter!&lt;/p&gt;

&lt;p&gt;See you in the next instalment!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>serverless</category>
      <category>webassembly</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building Nebula - Prologue: A beginning</title>
      <dc:creator>Marius Kluften</dc:creator>
      <pubDate>Thu, 19 Oct 2023 10:53:04 +0000</pubDate>
      <link>https://dev.to/brehen/-building-nebula-prologue-a-beginning-4d35</link>
      <guid>https://dev.to/brehen/-building-nebula-prologue-a-beginning-4d35</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A Function-as-a-Service platform powered by WebAssembly, built with Rust&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By now, you might have stumbled upon this well-known quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If WASM+WASI existed in 2008, we wouldn't have needed to created Docker.&lt;br&gt;
That's how important it is. Webassembly on the server is the future of&lt;br&gt;
computing. A standardized system interface was the missing link. Let's hope&lt;br&gt;
WASI is up to the task!&lt;br&gt;
&lt;a href="https://twitter.com/solomonstre/status/1111004913222324225?lang=en" rel="noopener noreferrer"&gt;&lt;em&gt;Solomon Hykes, founder of Docker&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's a bold statement that has been circulating ever since. I'm currently exploring this vision, where I've embarked on an adventure to build a FaaS prototype that exclusively runs WebAssembly modules. The goal? To discover the potential computational and energy efficiency such an approach might offer, forming the backbone of my master's thesis research.&lt;/p&gt;

&lt;p&gt;In essence, I aim to compare the performance and efficiency of predominant FaaS platforms - such as AWS Lambdas, Google Cloud Functions and Azure systems - against a system that rapidly initialises Wasm modules, executes the underlying function, and promptly shuts them down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding my Master thesis topic
&lt;/h2&gt;

&lt;p&gt;I'm building this prototype in order to perform some experiments for my Master's Thesis as part of my Master's degree in Programming and System Architecture at&lt;br&gt;
the University of Oslo. I initially started on this degree back in 2017, after achieving my bachelor's degree in Computer Engineering from OsloMet, but decided to jump off after the first semester when I got a job offer for working fulltime&lt;br&gt;
as a ServiceNow consultant.&lt;/p&gt;

&lt;p&gt;Ever since then, I've had 1/4th of a degree completed, and decided to pick it up again in 2022 and attempt to finish it part time. At UiO there's a clear preference for "long" master theses, meaning that 50% of your degree is made up&lt;br&gt;
of the thesis itself. In order to motivate myself to this undertaking that would occupy most of my free time, I decided to focus on what technologies I would like to see myself working on in the future, and was lucky enough to land a&lt;br&gt;
thesis project where I could dive into the Rust and WebAssembly ecosystem.&lt;/p&gt;

&lt;p&gt;I can attribute the initial idea for my master's thesis to the podcast episode &lt;a href="https://rustacean-station.org/episode/matt-butcher/" rel="noopener noreferrer"&gt;"Fermyon with Matt Butcher" from the Rustacaen Station Podcast&lt;/a&gt;. Fermyon is a Cloud company that are heavily invested in the WebAssembly space, and in the episode Matt Butcher, the CEO of Fermyon, tells the story of how Fermyon came to be, and why they decided to build a Cloud platform that only allows developers to run programs that can be compiled to WebAssembly. In his explanation, he mentioned that they observed rather insane startup times compared to more typical container based function-as-a-service offerings out there, going from comparable service in a Docker container taking &lt;strong&gt;300ms+&lt;/strong&gt; just to start up, down to &lt;strong&gt;sub 1ms&lt;/strong&gt; startup times for a comparable Wasm module delivering the same functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpk264n8rreyxlhn0oiny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpk264n8rreyxlhn0oiny.png" alt="Visual graph comparing startup time of Docker vs Wasm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Furthermore, as they advertise on their own&lt;br&gt;
&lt;a href="https://www.fermyon.com/#fermyon-benefits" rel="noopener noreferrer"&gt;webpage&lt;/a&gt; they saw that with Wasm modules they were able to achieve image/binary sizes down to ~1% of a comparable service packaged in Docker, from 230MB -&amp;gt; 3.2MB!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c3h8egq3pu59ao9mi9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c3h8egq3pu59ao9mi9f.png" alt="Visual comparison between a Docker image and Wasm module"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why purse a FaaS prototype?
&lt;/h2&gt;

&lt;p&gt;These metrics presented by Fermyon and the WebAssembly community are nothing short of remarkable. They've summarised their vision in the "third wave of cloud computing", with Virtual machines being the first wave and Containerisation&lt;br&gt;
(Docker) being the second wave. This begs the question: What kind of energy savings might we achieve if the industry leans more into these efficient cloud technologies?&lt;/p&gt;

&lt;p&gt;Guided by this curiosity - and with invaluable insight from my university supervisors - I formulated the hypothesis for my thesis:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is possible to develop a Pure FaaS platform that scale to near-zero&lt;br&gt;
resource usage, using WebAssembly modules&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's an ambitious objective, no doubt. Yet, this broad premise provides me ample space in how I end up building the prototype this fall. A cornerstone for this prototype? The principle of "pure" functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a "Pure" FaaS
&lt;/h2&gt;

&lt;p&gt;You've probably noticed the emphasis on "pure" in my hypothesis. In order to develop a prototype I can start experimenting on within the time-frame of a Master's thesis, I decided to scope it down to explore a FaaS platform that&lt;br&gt;
operate on pure functions.&lt;/p&gt;

&lt;p&gt;For those unaware of what a "pure function" is, it can be defined as such:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A pure function is a function that, given the same input, will always return&lt;br&gt;
the same output and does not have any observable side effect.&lt;br&gt;
&lt;a href="https://github.com/MostlyAdequate/mostly-adequate-guide/blob/master/ch03.md#oh-to-be-pure-again" rel="noopener noreferrer"&gt;Mostly Adequate&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This principle of purity assures consistent output for consistent output, a quality that opens up for interesting experimenting. This will allow me to explore some interesting orchestration and caching patterns for functions&lt;br&gt;
deployed to the platform, much like a hypothetical example illustrated below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F293u52wbaeeqf5uwuhxc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F293u52wbaeeqf5uwuhxc.png" alt="Simple illustration on a chain of function calls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naturally, building such a dynamic system has its challenges, and there's always a risk of overextending the scope of my thesis. Thus, my focus might lean more towards experimenting with pre-defined functions on the platform. We'll see!&lt;/p&gt;

&lt;p&gt;If you've journeyed with me this to this point, I really appreciate your time and interest! I'm excited about sharing more technical details down the line, and you can read more when my first chapter gets published!&lt;/p&gt;

&lt;p&gt;Link to repo: &lt;a href="https://github.com/brehen/nebula" rel="noopener noreferrer"&gt;https://github.com/brehen/nebula&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>rust</category>
      <category>cloudnative</category>
    </item>
  </channel>
</rss>
