[HN Gopher] WAGI: WebAssembly Gateway Interface
___________________________________________________________________
WAGI: WebAssembly Gateway Interface
Author : drocer88
Score : 91 points
Date : 2021-09-18 13:25 UTC (9 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| mbStavola wrote:
| I was working on something similar but I found that without
| interface types[1] you end up with a platform that's kinda
| primitive and pretty unergonomic. I honestly expect to see an
| explosion of projects in this vein once interface types are a
| real thing.
|
| [1]: https://github.com/WebAssembly/interface-
| types/blob/master/p...
| isaacimagine wrote:
| Imo, interface types are the only thing standing between Wasm
| and a Cambrian Explosion of Wasm plugin architectures. Up until
| now it's been go through JS or roll it yourself. Exciting
| stuff!
| nerdponx wrote:
| Does WebAssembly even make sense as a standalone runtime, like
| the JVM? Is "server-side WebAssembly" going to be "a thing", or
| is it just a compatibility kludge?
|
| And what of all these languages that compile to JS, like
| Typescript, Reason, Kotlin, et al? Is JS a sound "IR" between the
| frontend and WebAssembly? Or would it be better to compile things
| directly to WebAssembly?
| dgb23 wrote:
| There was a fairly recent article from Cloudflare providing
| tooling support for Rust->WASM on their Workers (serverless,
| sandboxed HTTP/Web centric plattform).
|
| WASM has some interesting properties, like sandboxing, a small
| set of instructions you can fit in your head and some fairly
| high level constructs (for a compilation target).
|
| However I don't quite know what other benefits it provides. It
| certainly cannot compete with the JVM/CLR on many fronts. And I
| don't see quite a lot of use-cases yet that cannot be covered
| with just integrating V8. Happy to learn more about that
| (actual rationales).
| japanuspus wrote:
| Not just for web either: if you ship WebAssembly bytecode as
| part of your python package, you can push your platform
| dependencies out to a wasm runtime and skip most of the build
| matrix.
|
| A runtime like wasmer-python [0] is only 1.5MB.
|
| [0]: https://github.com/wasmerio/wasmer-python
| fragile_frogs wrote:
| > If WASM+WASI existed in 2008, we wouldn't have needed to
| created Docker.
|
| Source:
| https://twitter.com/solomonstre/status/1111004913222324225?l...
| BiteCode_dev wrote:
| 1 - it's sandboxed by default
|
| 2 - it's the only things that also run on the web
|
| 3 - it's probably going to be ubiquitous because of that,
| meaning it will be a great platform to target by default
|
| 4 - it could potentially mean any platform run any code from
| any other one without having to deal with wrappers: you would
| write a lib in go or rust, and then run it as is in python
| pjmlp wrote:
| Someone just rediscovered IBM TIMI,Amsterdam Compiler Kit EM,
| CLR MSIL, among plenty of others.
|
| Sandboxing is of little help when external events can cause
| internal memory corruption that change module's expected
| outcomes.
|
| It is as good as typical OS process.
| gpm wrote:
| Yes, wasm makes sense as a standalone runtime. It's basically
| just like any other bytecode.
|
| Like any bytecode (including jvm's), it comes at a performance
| penalty over bare asm. I personally don't anticipate it will
| replicate jvm's success as being a runtime when there is no
| reason for a runtime to exist - since it shouldn't be much
| harder to compile wasm (and languages that compile to wasm) to
| native asm ahead of time. On the other hand I wouldn't have
| predicted jvm's success either.
|
| In places where you _want_ a runtime though, like in shared
| computation models where it gives you security /performance
| advantages, it makes perfect sense. It looks like it's probably
| going to succeed there to me.
|
| Compiling X -> JS -> Wasm doesn't make much sense. Not only is
| wasm a language with cleaner semantics to compile to, but JS
| doesn't actually really fit wasm semantics particularly well.
| In fact, while I could have missed something, I'm not aware of
| any good JS->wasm compilers. The closest I can think of is
| https://www.assemblyscript.org/ - and it's not 100% JS
| compatible.
| ignoramous wrote:
| > _Does WebAssembly even make sense as a standalone runtime,
| like the JVM? Is "server-side WebAssembly" going to be "a
| thing", or is it just a compatibility kludge?_
|
| Yes, see: https://bytecodealliance.org/articles/1-year-update
|
| > _Or would it be better to compile things directly to
| WebAssembly?_
|
| It'd be even better to roll out one's own Lambda@Edge:
| https://krustlet.dev/
| invokestatic wrote:
| I think a lot of people, myself included, have been waiting for
| a low-level, polyglot, and lighter weight runtime than the JVM.
| WebAssembly currently provides the best tooling for this. That
| said, I'm not really convinced of the server-side use case
| except for sandboxing untrusted code. Especially in rust, where
| the language itself provides safety guarantees that the VM
| makes redundant.
| zozbot234 wrote:
| The safety guarantees are not redundant, they're quite
| complementary. WASM doesn't protect you from violating memory
| safety _within_ your programs; its sandbox only protects the
| rest of the system from whatever the WASM program does.
| pjmlp wrote:
| Why waiting?
|
| There have been plenty of similar stacks, JVM is just one
| among many.
| simonw wrote:
| I think server-side WASM is going to be huge, because it could
| finally give us an easy to run code in a secure sandbox.
|
| Imagine being able to run a complex C dependency (with a high
| risk of buffer overflows) risk-free because it's running in a
| WASM sandbox?
|
| Or building features that allow users to provide their own
| executable code (for plugins and extensions and other
| customization features) where they code is executed in a
| sandbox with strictly controlled CPU/memory/network and API
| access control.
| Matthias247 wrote:
| I'm not sure the amount of C code that one wants to run into
| a server that is not system level code (doesn't make syscalls
| itself and implements the server/ business logic) is
| noticeable.
|
| And only if that would be the case the use of WASM would be
| an advantage. For general extensibility we had Java servlets,
| Lua modules, PHP modules, etc in webservers for decades.
|
| Maybe it's interesting for source code obfuscation purposes
| or in order to allow migration of server logic between
| different languages. But even that was possible before - and
| I don't think the Market need was huge.
| watermelon0 wrote:
| There are many tools such as ffmpeg, that you might want to
| run on untrusted input (e.g. file uploads), and in many
| cases performance is not that important.
|
| Java servlets, Lua and PHP modules cannot be run securely,
| and there are vulnerabilities for all of them.
| fiddlerwoaroof wrote:
| > Java servlets, Lua and PHP modules cannot be run
| securely, and there are vulnerabilities for all of them
|
| The thing is, the JVM was designed with the explicit
| intention of making it possible to run untrusted code
| safely: how do we know we got it right this time? The
| problem really isn't the VM, it's the APIs and
| authorization model for access to the underlying system's
| features.
| gpm wrote:
| Because browsers have a good track record of getting this
| right, and sufficient funding to get this right, and the
| server-side work gets to piggy-back on that.
|
| Also because the API surface area that server side apps
| need is really just not big, JVM had a lot of problems
| because it tried to do too much.
| simonw wrote:
| I want to use the best-of-breed libraries for image
| handling, movie decoding and suchlike - and most of those
| are still written in C.
| croes wrote:
| If you want safe code you have to write safe code. Putting it
| into a sandbox gives you fake security.
| wtetzner wrote:
| > If you want safe code you have to write safe code
|
| That doesn't help if you need to run other people's code.
| croes wrote:
| Then you have to forgo safety.
| simonw wrote:
| Tell that to Heroku, GitHub (Actions), Vercel and the
| whole of AWS, Google Cloud and Microsoft Azure! Running
| other people's code is a multi-billion dollar business
| opportunity.
| croes wrote:
| Since when does multi-billion dollar opportunity corelate
| with safety?
| skybrian wrote:
| Running untrusted code in a sandbox made client-side web
| apps possible, so I think there's more to it than that.
| croes wrote:
| But you wouldn't say it's safe just less unsafe.
| skybrian wrote:
| Maybe safety isn't binary? We are usually more
| sophisticated about evaluating risks than that.
|
| If all you think about is whether things are safe versus
| unsafe, everything is "fake security" and you'll never
| come up with defense in depth.
| pjmlp wrote:
| You mean like CLR or IBM mainframes language environments?
|
| Yeah, I wonder how it would look like. /s
| irq-1 wrote:
| Right. WASM will protect _the server_ from the apps, which
| means you don 't need to audit or trust what you run. That
| old PHP website? Compile to WASM and you might lose any data
| it can touch, but it won't expose the server in any way -- no
| getting a login shell or sudo exploits, etc...
| nerdponx wrote:
| Forgive me if this is a newbie question, but what makes the
| Wasm runtime more of a "sandbox" than e.g. CPython or the
| JVM? Do you need explicit permission/authorization from the
| host machine in order to do things like file and network
| i/o? Surely such a system isn't any more foolproof than SSH
| w/ a restricted shell, KVM, etc.?
| astlouis44 wrote:
| WebAssembly gaming is going to be huge.
| fnord77 wrote:
| so this is like WSGI? The almost 30 year old design pattern that
| blocks on requests waiting for a response from the downstream app
| and really isn't scalabe?
| supermatt wrote:
| wsgi isnt inherently blocking. it is a protocol and it is up to
| the implementation on both sides if the interface as to how it
| is handled.
|
| that said, according to the docs this seems to be cgi 1.1 which
| equates to a process per request, which afaik isnt so scalable.
| zozbot234 wrote:
| WASM "processes" need not be the same as OS-level processes.
| So I don't think this would have the scalability issues of
| plain CGI.
| supermatt wrote:
| interesting! i will have to have a look into this
| Matthias247 wrote:
| Right. And the Wasm runtime could run multiple Wasm
| processes on one OS thread. If one program blocks on
| stdin/stdput it gets descheduled and the next one can run.
| Which basically provides the same M:N scheduling that
| highly scalable Webservers would use.
| formerly_proven wrote:
| It's not, this is a CGI implementation. WSGI is an in-process
| API and can support multiple requests in flight. Kind of weird
| to call this a gateway interface instead of something like
| wasm_cgi.
|
| > Wagi is an implementation of CGI for WebAssembly.
| giancarlostoro wrote:
| ASGI is the replacement for WSGI. Honestly I never noticed
| insane latency with WSGI.
| als0 wrote:
| Can anyone recommend a good introduction to WASM and WASI?
| Something that covers standalone and browser based?
| isaacimagine wrote:
| 1 minute intro:
|
| Wasm is a high-level assembly language that has both a textual
| and binary format. It can be interpreted or compiled to a
| native representation, and has tight integration with modern JS
| engines (though JS is not required to run Wasm).
|
| WASI (WebAssembly System Interface) is a runtime environment
| standard for Wasm that allows Wasm applications to integrate
| with 'standard' Unix APIs. These can be forwarded to the host
| system or emulated.
|
| For more info, honestly just going to the Wasm site, the
| standard, or one of the runtime implementations and exploring
| from there is the way to go.
|
| It's best to learn by doing, so if you know a language that can
| compile to Wasm, it's always a fun project to try to write
| something using it. Rust, D, C, Zig, and AssemblyScript all
| have pretty good tooling.
|
| Hope this helps!
| nynx wrote:
| Why would they put things in environment variables instead of
| having new imported functions to grab various values?
| the_duke wrote:
| I think the goal with this one was to be zero-friction and
| allow any WASI module to serve requests, without requiring
| language-specific bindings.
|
| It's obviously not a great design, and a more serious
| standardized version would use interface types. But that still
| seems quite a ways off.
| tyingq wrote:
| That's what the various CGI specs require, and the project is
| to implement something very close to CGI in WASM.
| puppet-master wrote:
| Reproducing ancient defects from the CGI spec in the process,
| such as the inability to represent duplicate header names.
| guntars wrote:
| Wonder why they wouldn't pass in the whole request on
| stdin? That would also mean that instances could be pre-
| started in anticipation of a request and not just when one
| is already waiting.
| Matthias247 wrote:
| To allow processing of large request and response bodies.
| Imagine a 1Gb PUT or GET. You don't want to spend 1Gb RAM
| for handling those. And you also don't want to wait
| multiple minutes to hours to have the body buffered and
| can actually present it to application logic.
| guntars wrote:
| Not sure I follow. A reasonable framework would stream
| both the incoming request as well as the response. If the
| WASM module wants to read the whole thing into memory,
| it's free to do so, but you could have it process the
| request piecemeal. It's just reading the request from a
| file descriptor and writing the response to another one.
| Not that different when those fds are actually sockets.
| Matthias247 wrote:
| Oh sorry. I misread it and thought you are asking why the
| request isn't passed in complete form as an environment
| variable too. I guess you are asking why the request
| headers are not transferred via stdin too? My guess it's
| just because that's how CGI works. It prevents from
| having apps do the parsing work. Plus what could be
| passed wouldn't be the original request anyway. If the
| Webserver handles http2 or http3 headers would always
| need to be repacked into a format that the script
| understands.
| tyingq wrote:
| On passing environment variables instead of the full
| request, probably to make it more accessible to get
| started with the existing popular languages (C, Perl,
| Tcl, Shell Scripts, mostly) without having to write all
| the request parsing. There was also less "stuff" in the
| request than today. No cookies, no file uploads, and so
| on. They also passed things in that weren't in the
| request itself, like REMOTE_ADDR, REMOTE_HOST,
| SERVER_PORT, PATH_INFO and so on. So it seemed natural to
| just put everything in environment variables, other than
| the $CONTENT_LENGTH bytes that followed the header.
|
| As for the fork() per request, I believe mostly because
| they were starting with requirements where avoiding
| fork() wasn't important. Conserving memory was probably
| more important, given the timeframe. CGI programs that
| leaked memory would have been common if they were
| daemons. For most web servers, there also probably
| weren't that many requests.
|
| It was also a common existing pattern. Many of the
| services on unix boxes worked the same way...one daemon
| (inetd) would start instances of daemons per request and
| they would serve only one request.
|
| That said, NSAPI appeared pretty quickly after CGI, then
| FastCGI, etc. Still pushing environment variables for
| headers, but stopping the request->fork->exit pattern and
| allowing persistent daemons.
| tyingq wrote:
| RFC2616 says this:
|
| _" It MUST be possible to combine the multiple header
| fields into one "field-name: field-value" pair, without
| changing the semantics of the message, by appending each
| subsequent field-value to the first, each separated by a
| comma."_
|
| So, if the implementation folds the multiple headers into
| one with the various values as a comma separated list, it
| should all be compliant. I don't know rust well enough to
| tell if this one is compliant...it reads like it is not
| (looks like last header wins): https://github.com/deislabs/
| wagi/blob/main/src/http_util.rs#...
|
| Edit: It seems RFC7230 keeps most of that language, but
| makes one exception for Set-Cookie, but that's outbound in
| this context so it doesn't apply.
| fleetfox wrote:
| Interesting. What about web sockets?
| gavinray wrote:
| This is awesome to see!
|
| I have been working on something like this for a while too. But
| it uses GraalVM and it's "Polyglot" runtime to provide support
| for JS/Ruby/Python/WASM/LLVM languages.
|
| It's packaged as a single binary using graal-native + Quarkus, or
| if you don't care about that (faster startup time/lower memory
| use/no JVM needed) but need maximum performance, you can run it
| as a regular JVM service as well.
|
| It was born out of a need for a polyglot Functions-as-a-Service
| platform but without the weight of container orchestration -- I
| needed something I could deploy as a single binary.
|
| Essentially OpenFaaS/OpenWhisk, minus containers.
|
| It doesn't use CGI as a request/response specification though, it
| uses Vert.x "RoutingContext" interface which has methods like
| _".getBodyAsJson() "_, _".params( 'something')"_, _".header(
| 'foo')"_, etc. https://vertx.io/docs/apidocs/io/v
| ertx/ext/web/RoutingContext.html
|
| An open standard like CGI probably would have been better, but
| Graal has marshalling facilities for sharing object types between
| languages, so the most user-friendly/ergonomic thing to do was to
| share the underlying web request object itself across language
| boundaries, including all the methods you can call on it.
|
| ---
|
| This has given me motivation to finally finish it so I can
| publish + open-source it!
| luckystarr wrote:
| This looks like CGI on WebAssembly. Do the wagi scripts have to
| be spawned upon every request, or can the somehow persist in
| memory?
| iampims wrote:
| They are loaded at boot an executed for each matching requests.
___________________________________________________________________
(page generated 2021-09-18 23:01 UTC)