wasmedge-quickjs
wasmedge-quickjs copied to clipboard
Run as a Cloudflare worker
- [ ] Cloudflare recently added support for Wasm and offers a Rust SDK with compile target wasm32-unknown-unknown. Certain JS language features, like eval(), which are disabled in the web worker for security reasons, could run safely in the wasm sandbox as embedded js, using quickjs. Naturally, the target for wasmedge_quickjs is wasm32-wasi, given the purpose is to embed js in the wasmedge runtime.
Thanks. I have not tried this. But can you take a few serverless function examples from cloudflare workers docs / examples, and try them in WasmEdge_quickjs? I am curious if they can run.
Got this to work after removing http and sockets libs and setting target to wasm23-u-u. Then setting [dependencies]
of Cargo.toml of the worker template to: wasmedge_quickjs = { git = "https://github.com/tysonrm/wasmedge-quickjs", package="wasmedge_quickjs" }
. Will add some sample code...
Almost...need to get rid of imports / provide impl for some std libs... https://github.com/tysonrm/rustwasm-worker-template
use serde_json::json;
use wasmedge_quickjs::*;
use worker::*;
mod utils;
fn js_hello(ctx: &mut Context) {
println!("\n<----run_simple_js---->");
let code = r#"print('hello quickjs')"#;
let r = ctx.eval_global_str(code);
println!("return value:{:?}", r);
}
#[event(fetch)]
pub async fn main(req: Request, env: Env) -> Result<Response> {
let mut ctx = Context::new();
js_hello(&mut ctx);
Uncaught Error: LinkError: WebAssembly.Instance(): Import #41 module="env" function="fopen" error: function import requires a callable at line 0 [API code: 10021]
If it's possible to provide bindings to cloudflare for io that would most likely do the trick.
With emscripten and quickjs, I can get code to execute but as soon as I attempt to add host functions at runtime, like “fetch” with VM.newFunction - cloudflare throws assertion errors because I cannot instantiate WASM from a unit8array (the host2cCallback)
rust is advantageous because you can declare bindings easily during build. Doing this in C, I’d imagine I’d have to take the host callback and somehow generate a WASM file, then deploy it up independently.
Hi @ScriptedAlchemy
Could you elaborate what kind of Cloudflare I/O bindings we should implement? Sorry I am not very familiar with the Cloudflare setup. WasmEdge provides a networking socket API, and can support host functions (wrappers) to interact with external systems. We would love to make it work with Cloudflare. :)
Cheers Michael
If you have any time for a call with @tysonrm and myself, and we would jump at the opportunity to work together.
These binding would cover all Io on CF. Mainly we need fetch, request, response. But most importantly would be fetch capabilities https://github.com/cloudflare/workers-rs
So here's a workaround: we can have a js worker instantiate quickjs and pass in a js function it can call to invoke fetch. As for the rust solution, under the hood its actually js based anyway. It's just a js worker that instantiates the wasm module. This will change when they roll out their wasi based solution, but we are already set up for that.
Hi @ScriptedAlchemy and @tysonrm
Thank you so much for your ideas and experiments. Perhaps we can schedule a call to discuss these in the first week of the new year?
The Cloudflare Rust crate is designed to be compiled into wasm, right? Are we trying to run their compiled wasm bytecode in WasmEdge? Or do we plan to use the WasmEdge APIs in Cloudflare's v8 runtime?
Cheers Michael
A call would be great. Thanks, Michael. Yes, the crate compiles to wasm. Our goal right now is the latter. That said, they are also looking at supporting a wasm based runtime.
- [ ] Cloudflare recently added support for Wasm and offers a Rust SDK with compile target wasm32-unknown-unknown. Certain JS language features, like eval(), which are disabled in the web worker for security reasons, could run safely in the wasm sandbox as embedded js, using quickjs. Naturally, the target for wasmedge_quickjs is wasm32-wasi, given the purpose is to embed js in the wasmedge runtime.
I also spoke with jake the maintainer of wuickjs emscripten. Who gave me a snippet to add extra bindings to C during compile time. Like console log so wasm comes out the box with extra host bindings. Not sure about fetch though.
Is there a better way we can coordinate a time to chat? Slack? Email?
We are highly motivated to see this through. Combined with our work on module federation, if we have quick + edge workers + module federation, we can essentially compute any code without any deployment or software installation ahead of time.
This would effectively nullify the need for AWS for a large portion of users.
With quick and cloudflare + federation. I can host about 1 million unique codebases with 0.5ms startup time per worker.
Compared to aws, which takes 1200ms to cold start a lambda - we can create about 1,000 environments and respond to 1000 requests to each env in less time than it takes to start that aws lambda.
We can update any codebase or part of it on the fly without ever redeploying or binding software to a specific deploy time artifact.
The largest roadblock we face on edge network is I cannot fetch() inside quick because of host function binding at runtime vs create bindings for fetch() at build time.
As Tyson said, edge providers disable certain code generation capabilities in V8, but if I don't use v8 I am not confined by their limits and it's far more secure. We can also have an edge worker execute up to 25mb of js through our mechanism compared to cloudflares 1mb limit they have today.
Sure. My email is [email protected]
You can find me using the same email on Slack. I can see @tysonrm on CNCF's Slack. @ScriptedAlchemy if you are in CNCF slack too, we can form a channel. :)
So here's a workaround: we can have a js worker instantiate quickjs and pass in a js function it can call to invoke fetch.
Hey, @tysonrm any rough code example on how this would work?
Sorry for the long delay. The code at this link shows Node.js instantiating a wasm module whose imports include a function that publishes events to an event broke nning in Node.js.
Did this ever get sorted? Very interested in this too