[HN Gopher] Launch HN: Lunatic (YC W21) - An Erlang Inspired Web...
       ___________________________________________________________________
        
       Launch HN: Lunatic (YC W21) - An Erlang Inspired WebAssembly
       Platform
        
       Hi HN! We're Bernard & Hrvoje and we are Lunatic
       (https://lunatic.solutions/). Our goal is to improve how you run
       server-side code by building an open-source runtime that gives you
       lightweight processes, fault tolerance, and capability-based
       security for different parts of the application. Basically, we want
       to combine the power of Erlang with WebAssembly and bring that to
       new and existing applications.  The two of us met in high school,
       studied computer science together, but then went separate ways
       working as backend engineers. Bernard worked at CERN and Hrvoje co-
       founded Amodo, an insurance tech startup. Bernard, being a huge fan
       of Erlang/Elixir, started working on a similar open-source runtime
       for WebAssembly which he called Lunatic
       (https://github.com/lunatic-solutions/lunatic).  Lunatic runs Wasm
       modules as lightweight processes with its own heap/stack and
       preemptively schedules them on a multi-threaded executor. You can
       spawn those processes using a library we provide (currently for
       Rust and AssemblyScript) to enable actor-based architectures with
       message passing. Scheduling is implemented by modifying a Wasm
       module and adding "reduction counts" (similar to Erlang). You can
       write seemingly blocking code but it won't actually block the
       underlying OS thread as our implementation of WebAssembly System
       Interface (WASI, think of it as POSIX syscalls) will be implemented
       with async Rust and a bit of magic [0] :) The code is JIT'ed and we
       build on top of existing Wasm runtimes Wasmtime/Wasmer for this
       part (codegen is done by LLVM or Cranelift).  To step back from
       technical details, working on Lunatic for the past few months, we
       have started to form a bigger picture about server-side
       applications. Over the years we have witnessed many trends: Docker
       & containers became popular, asynchronous programming and green
       threads are ubiquitous for IO intense work, polyglot codebases are
       always present, microservice architecture became popular, and
       distributed is being used both for scale and to bring computation
       closer to clients to lower latency. Two important driving forces
       are hardware capabilities and how we develop software. Those have
       changed dramatically from the time operating systems were created.
       For example, to maximize resource usage of a single machine, we
       started running virtual machines and then moved to more lightweight
       containers, both to give isolation and sandboxing to different
       applications. Serverless is pushing this even further. Lunatic
       builds on top of WebAssembly security principles [1] to give
       sandboxing and isolation to enable even more lightweight
       environments.  Servers also needed to handle more and more network
       connections and spawning an OS thread per connection became
       problematic so developers used different programming patterns,
       async implementations, or user-space threads/processes to tackle
       this problem. Lunatic solves this by using Erlang's proven approach
       [2].  How we develop software has also changed. Today most of our
       application consists of third-party libraries and it's common to
       have hundreds or even thousands of dependencies and obviously it's
       impossible to audit them all. When you compile and run your
       application, the whole code has the same privileges, so a malicious
       dependency could easily steal your private keys.[3,4,5] WebAssembly
       is trying to standardise ideas like Interface Types and dynamic
       linking between Wasm modules. We could isolate libraries into
       different modules based on capabilities they require (which "system
       calls" they use) and let developers decide which parts of their app
       have what capabilities.  Other use-cases that Lunatic and Wasm
       enable are plugin architecture to run third-party code, sharing
       code between frontend and backend, polyglot codebases that use Wasm
       interface types to call each other functions, etc.  Currently
       Lunatic is just a runtime but ultimately we want it to be more like
       an operating system for server-side applications. The value we want
       to give to developers is simpler deployment and management of
       running apps, better capability-based security model, and seamless
       integration with third-party tools (logging, monitoring,
       profiling). Ideally all you need to do is compile your app to
       WebAssembly and you are ready to go.  We have built two demo apps
       to showcase Lunatic. Lunatic.run (https://lunatic.solutions/run/)
       turns any command line application into a web server endpoint. Read
       HTTP requests from stdin and respond to stdout. The other is
       Lunatic.chat, a telnet chat server written in Rust using actor-
       based architecture (https://github.com/lunatic-solutions/chat).  We
       are super excited to work on these problems and we hope we have
       managed to convey some of that excitement to you. Please share with
       us your thoughts and questions. Does our big picture resonate with
       you? Would you like to use a runtime like Lunatic? Do you have some
       other use-cases in mind?  [0] https://crates.io/crates/async-
       wormhole [1] https://webassembly.org/docs/security/ [2]
       https://www.phoenixframework.org/blog/the-road-to-2-million-... [3]
       https://news.ycombinator.com/item?id=26087064 [4] https://jordan-
       wright.com/blog/post/2020-11-12-hunting-for-m... [5]
       https://snyk.io/blog/yet-another-malicious-package-found-in-...
        
       Author : withtypes
       Score  : 123 points
       Date   : 2021-03-06 12:49 UTC (10 hours ago)
        
       | iamwil wrote:
       | It seems like lunatic is an open source lib with two different
       | licenses. Is it that you can pick either one? Or is it
       | the...union of the two licenses?
       | 
       | It's probably early, but how are you planning on making money? If
       | I build on top of this, I don't want the rug to be pulled out
       | from under me.
        
         | bkolobara wrote:
         | Yes, you can pick the one you prefer. Regarding making money,
         | we have not worked out the details and we would definitely like
         | to include feedback from the community. The core will stay open
         | source, we might build some plugins/integrations under a
         | different licence and offer a hosting service.
        
       | weego wrote:
       | There's an awful lot of verbiage but none of it really tells me
       | in why or what situations or domains I'd find this compelling.
       | I'm impressed conceptually but like are we talking 'bring your
       | favourite language to a highly fault tolerant nodejs
       | replacement'? Or I'm off the mark? The site is similarly vague.
        
         | withtypes wrote:
         | You are thinking in the right direction, but there are some
         | technical differences between how NodeJS works compared to
         | Erlang or Go. For example, in NodeJS you could accidentally
         | block the event loop by some unintended computation, but
         | Lunatic and Erlang periodically give control back to the
         | runtime. We also want to abstract the syscall layer, for
         | example, in our lunatic.run demo, you write a program which
         | seemingly uses standard input/output but we actually read/write
         | from a socket.
         | 
         | By the way, if it sounds vague, that's important info for us,
         | we have to improve that!
        
       | fgmalpha wrote:
       | It would be great if you guys could participate in the stack
       | switching effort in the Wasm CG.
        
         | bkolobara wrote:
         | We want to work closer with the Wasm CG in the future and help
         | with the standardisation process and adoption of WebAssembly. I
         | am not aware of a stack switching effort going on, could you
         | provide a link to the discussion?
        
           | bitwalker wrote:
           | Meetings are scheduled here, along with their planned
           | agendas: https://github.com/WebAssembly/meetings/tree/master/
           | stack/20...
        
       | iamwil wrote:
       | how come Lunatic supports both wasmtime and wasmer? Why those two
       | runtimes and why not some other one like wasm3?
       | 
       | I'm not for or against any of them. I'm just wondering what
       | criteria there was in choosing those two rather than any others,
       | since I only have a cursory overview of the different WASM
       | runtimes.
        
         | withtypes wrote:
         | Wasmtime/Wasmer are both written in Rust so it was easy to
         | integrate them. By the way, Wasm3 is an interpreter, not a JIT
         | compiler, but this also has some use cases! For example,
         | running an instance from "cold storage" requires a JIT
         | compilation step which might take more time then just
         | interpreting it. It would be cool to have a fast interpret like
         | Wasm3 too.
         | 
         | We've created a crate "uptown_funk" which enables us to write
         | Rust code which easily integrates with both Wasmer and
         | Wasmtime. It was very helpful in implementing WASI and it takes
         | a little bit different approach than Wasmer and Wasmtime.
         | Regarding, Wasmer vs. Wasmtime, we don't have a preference yet,
         | both are great!
        
       | nojvek wrote:
       | I 100% agree with some of the trends you mentioned
       | 
       | 1) lightweight isolated computation - VMs, containers and the
       | lot.
       | 
       | 2) asynchronous io - user space green threads, epoll, event loops
       | and the likes to have single OS process handle 1000s of
       | connections
       | 
       | 3) distributed - scale up compute + have it run close to user.
       | Cloudflare workers, edge@lambda, fly.io. They're all moving to
       | this direction.
       | 
       | 4) polyglot micro services - rather than one big thing written in
       | a single language, many small things that talk to each other via
       | HTTP & grpc. They can be independently changed and scaled up
       | without having to restart the whole system.
       | 
       | Erlang + webassembly are a great fit for this paradigm.
       | 
       | Seeing the success of fly.io, Cloudflare workers and other cloud
       | providers, this definitely has legs and I would love to try it
       | out.
        
         | withtypes wrote:
         | Fly.io is doing cool stuff! We will try out their platform to
         | deploy Lunatic to the edge.
        
         | amelius wrote:
         | > lightweight isolated computation
         | 
         | Sounds good, as long as we can have structural sharing between
         | processes on the same CPU, for performance.
        
       | rapsey wrote:
       | You have a very tough road ahead (as a business). Not because you
       | are not making sense, but because widespread tech adoption is fad
       | based and generally a function of two factors. Who is behind them
       | (google with go, netflix with microservices) and low barrier to
       | entry (mongodb, node.js).
        
         | bkolobara wrote:
         | We have an advantage here because we are building on top of
         | existing technologies (WebAssembly, Wasmer, ...), but combining
         | them in a novel way. Developers in our community are already
         | building web frameworks in Rust, while utilising features of
         | Lunatic today. I believe that being able to provide value this
         | early is going to play an important role in widespread
         | adoption.
        
       | skybrian wrote:
       | How does communication between the lightweight processes work?
       | What do the messages look like? Are they copied?
        
         | bkolobara wrote:
         | Yes, the data is copied from the memory of one process to
         | another. In the future we want to use the WebAssembly multi-
         | memory proposal to allow processes to share data without
         | copying and reduce overhead in certain cases.
        
       | eyberg wrote:
       | Has there been any traction or even ideas on fixing the issue
       | that there is no read-only memory in web assembly?
       | 
       | Sounds completely unsafe to use without.
        
       | maxmcd wrote:
       | Hey, I tried to build something like this too:
       | https://github.com/embly/embly
       | 
       | My takeaway after building that is that the build tooling is the
       | major pain point. If you're trying to onboard someone onto this
       | platform from their favorite language the hard part is getting
       | from code to the .wasm file. wasm-bindgen (as an example) has put
       | so much effort into build tooling, I wonder if that's a necessary
       | path for success here. (edit: this also might be out of date,
       | maybe wasi solves a lot of this)
       | 
       | It's also great that WASI exists now, if I had to do embly again
       | I'd just use wasi and then implement all of my "platform"
       | features as filesystem features, not syscalls. If your API
       | interface is the filesystem then you could provide
       | interoperability between environments. Let's say you want to
       | include a key-value store in the wasi runtime, you just make the
       | keys files and the values file contents. Then you could so
       | something like ship a FUSE filesystem to interact with the
       | filesystem in the same way from a traditional VM or on a personal
       | computer. I got really bogged down in custom syscalls and this
       | path seems potentially more elegant.
       | 
       | Have you also thought about live process migration? I got really
       | excited about this from a technical standpoint. Since you
       | completely control the runtime you could set up a clustered wasm
       | solution that moves long running processes from VM to VM by
       | sending their live memory state to another machine. Not sure if
       | that's actually useful, but cool that it's not bogged down by the
       | usual complexities of doing the same in a full OS environment.
       | 
       | Anyway, so glad to see this. Please make a cloud platform and let
       | me pay for it. Also happy to chat more if any of this is useful,
       | I've joined your discord as "max".
        
         | bkolobara wrote:
         | We are investing a lot of effort into making Lunatic feel
         | native to the particular language and ecosystem. If you look at
         | the Rust chat server we built in Lunatic
         | (https://github.com/lunatic-solutions/chat), it fully
         | integrates with cargo. You just run your typical "cargo run"
         | command, it will compile the app to wasm and use lunatic to run
         | it. If you want to run your test, you can just do "cargo test".
         | 
         | wasm-bindgen is necessary only because it's really hard right
         | now to merge the wasm world and the JS one in the browser. We
         | have the advantage here of staying out of the browser.
        
           | elcritch wrote:
           | It'd be great to see C/C++ be easy to integrate. I can't
           | quite tell if there's support for them? There's so many
           | existing C/C++ code bases that are security nightmares but
           | still provide great functionality. Wrapping it in a secure
           | context would be awesome.
           | 
           | Also it'd be fantastic to be able to compile Nim as well.
           | Maybe a weekend project. :-)
        
             | bkolobara wrote:
             | C/C++ has great WebAssembly support and we definitely want
             | to provide a Lunatic library for it. We would love to see
             | the community getting involved and contributing other
             | languages that we have less experience with, including Nim.
        
               | elcritch wrote:
               | If you provide a C library then it'll be super easy to
               | add Nim support!
        
         | withtypes wrote:
         | We will take a look at embly! For Rust currently you just have
         | to add wasm32-wasi target and compile for it. There are still
         | some problems (WASI is not yet finished, maybe binary size
         | could be optimized). Our current idea is to build a small cargo
         | command which would do building and deploying. Wasmer is doing
         | great work with tooling for other languages. We are now focused
         | on Rust and AssemblyScript, but as Wasm and WASI mature we
         | would like to simplify it for more languages.
         | 
         | We have been thinking about live process migration. I'm
         | planning to do a demo where we run a lot of board games (e.g.
         | chess) on authoritative servers using Lunatic. Then we give a
         | developer ability to move a live game to a different machine
         | without players noticing. We are still working out the details,
         | but that area also excites us!
        
           | infogulch wrote:
           | Factorio is a 2d game where logistics is one of the core
           | problems players have to solve. When they implemented
           | multiplayer they went for the "every player/server simulates
           | the whole game perfectly deterministically"-strategy which is
           | great imo, but it begs the question: what happens when
           | simulations diverge? They call it Desyncronization [1], and
           | it's considered a bug.
           | 
           | They had lots of desyncs at first, but nowadays Factorio is
           | fantastically stable in this respect. One of the tools they
           | developed for themselves to achieve this (and the reason why
           | I'm bringing up Factorio here) is called "Heavy Mode" [2],
           | which is a game option that saves & reloads the full game
           | state on _every tick_ (the game targets 60 ticks /s), and
           | compares the before/after states for inconsistencies.
           | 
           | Perhaps a similar "Heavy Mode" for Wasm live migrations could
           | aid in hardening such a feature. E.g. spawn two instances of
           | the same process on different hosts, and migrate both to new
           | hosts every, say, 100k instructions, comparing a hash of
           | their serialized representations at each migration.
           | 
           | [1]: https://wiki.factorio.com/Desynchronization
           | 
           | [2]: https://www.factorio.com/blog/post/fff-63
        
       | dataangel wrote:
       | My excitement around Lunatic is mostly from being able to write a
       | native application in Rust that I know won't have memory issues
       | (b/c Rust borrow checker) and where I know bad plugins can be
       | reliably killed (b/c lunatic reduction counts) without killing
       | the whole application. Trying to be an OS replacement sounds
       | cool, but I hope lunatic doesn't lose sight of this already
       | worthy use case :) As soon as lunatic has a way for me to link
       | native libraries (e.g. making lunatic usable as a library for a
       | regular Rust app, so the core can call native libs) and supervise
       | processes (so I can kill the bad plugins) I'm all aboard.
        
         | withtypes wrote:
         | We agree with you, we are currently focused only on runtime
         | running on an existing OS. We know there are different uses-
         | cases so we could organize the project so that you can use what
         | you need. In theory, you could use it right now inside of your
         | Rust app to run plugins as Lunatic processes, but we need to
         | document it a little bit better and maybe showcase an example.
        
       | ibraheemdev wrote:
       | Previous discussions about Lunatic:
       | 
       | https://news.ycombinator.com/item?id=25160474
       | 
       | https://news.ycombinator.com/item?id=25253070
        
       | bglusman wrote:
       | Curious how this differs from Lumen? I guess it's not aiming for
       | actual ability to target Lunatic with BEAM languages, but that
       | seems like a disadvantage rather than an advantage, so curious
       | what the advantages are? I guess focus on integration/OS like
       | services perhaps?
       | 
       | https://getlumen.org/ https://github.com/lumen/lumen
        
         | bkolobara wrote:
         | We have different goals from Lumen. Lumen is bringing BEAM
         | languages to WebAssembly by running the whole Erlang runtime
         | inside a WebAssembly instance. Lunatic is bringing the concepts
         | of Erlang (fault tolerance & concurrency) to other languages.
         | We are using WebAssembly instances as a replacement for
         | Erlang's processes. This gives us even stronger per process
         | isolation.
        
       ___________________________________________________________________
       (page generated 2021-03-06 23:00 UTC)