Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submit Your Feature Requests and Ideas #10

Open
sebastianwessel opened this issue Jul 8, 2024 · 18 comments
Open

Submit Your Feature Requests and Ideas #10

sebastianwessel opened this issue Jul 8, 2024 · 18 comments
Assignees
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed question Further information is requested

Comments

@sebastianwessel
Copy link
Owner

If you have ideas, wishes, feature request and feedback - please add them in the comments below

@sebastianwessel sebastianwessel added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed question Further information is requested labels Jul 8, 2024
@sebastianwessel sebastianwessel self-assigned this Jul 8, 2024
@sebastianwessel sebastianwessel pinned this issue Jul 8, 2024
@sebastianwessel sebastianwessel changed the title Feature Requests and Ideas Submit Your Feature Requests and Ideas Jul 8, 2024
@sebastianwessel sebastianwessel removed the bug Something isn't working label Jul 8, 2024
@poef
Copy link

poef commented Jul 12, 2024

Can I also inject javascript objects from the main process into the QuickJS runtime? I'm building a node express based data server, where I want to allow clients to run javascript queries on that data (https://github.com/SimplyEdit/SimplyStore/)

@sebastianwessel
Copy link
Owner Author

Hey @poef

Yes, you can. See Data Exchange Between Host and Guest
You can use env, and provide strings, numbers, arrays, objects and functions.

const { evalCode } = await createRuntime({
  env: {
    MY_PROCESS_ENV: 'some environment variable provided by the host',
    KV: {
      set: (key: string, value: string) => keyValueStoreOnHost.set(key, value),
      get: (key: string) => keyValueStoreOnHost.get(key),
    },
  },
})

@guest271314
Copy link

Read standard input to V8's d8 (/proc/PID/fd/0) with WebAssembly. Right now I'm using QuickJS via os.system() https://github.com/guest271314/native-messaging-d8/blob/quickjs-stdin-read/nm_d8.js#L16, https://github.com/guest271314/native-messaging-d8/blob/quickjs-stdin-read/read_d8_stdin.js. If we can do this with WebAssembly we can get rid of os.system() which call sh.

@sebastianwessel
Copy link
Owner Author

sebastianwessel commented Jul 12, 2024

@guest271314 thanks for your feedback. As far as I understand, if the "regular" deadline nodejs module is available inside of the quickjs runtime, it should solve the issue or?
So, the code inside the sandbox would look like this

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

rl.on('line', (line) => {
    console.log(line);
});

rl.once('close', () => {
     // end of input
 });

@guest271314
Copy link

As far as I understand, if the "regular" deadline nodejs module is available inside of the quickjs runtime

Where does Node.js API's get in to your WASM QuickJS build?

The idea is to use the least amount of resources to read d8 shell standard input. QuickJS (quickjs-ng) is around 1.2 MB.

I was thinking I could use WebAssembly/WASI to read stdin to d8 using WebAssembly.compile().

@guest271314
Copy link

I'm basically trying to do this https://github.com/guest271314/native-messaging-webassembly without a WASM runtime, using the built-in WebAssembly object alone - within d8. I created a different solution for Mozilla SpiderMonkey.

@sebastianwessel
Copy link
Owner Author

What I was meaning is, that you can provide functions and data from a regular Node.js host application, to the wasm guest system.
Basically, you would read the standard-in in the host application and provide this data than to the guest system, as a copy.
What you try is, to disable the isolation of the wasm, and to allow to access the host system directly. Kind of disable security and enhance WASI in the direction of wasix.
In this project, this not wanted, as the JavaScript should run in an isolated sandbox, ensuring that it is not possible to break out, and access host functionality directly, in an uncontrolled manner.

@guest271314
Copy link

What I was meaning is, that you can provide functions and data from a regular Node.js host application, to the wasm guest system.

It doesn't make sense to me to use 108.7 MB node executable that depends on V8 to read standard input to v8 at 37.9 MB.

I use deno and bun and qjs and tjs the same that I use node, so I don't think of node as a "regular Node.js application". node is just another JavaScript runtime in the JavaScript toolbox for me.

That's why I chose qjs at 1.2 MB to do the task.

I have been trying to do this using d8s readline(), though have not succeeded, yet.

I saw your work and this issue requesting features and decided to place a feature request.

In this project, this not wanted, as the JavaScript should run in an isolated sandbox, ensuring that it is not possible to break out, and access host functionality directly, in an uncontrolled manner.

I don't think it is possible to achieve that requirement. I have broken out of too many alleged "sandbox" to think for a moment that it can't be done in this case, too.

Thanks!

@sebastianwessel
Copy link
Owner Author

Hey,
No worries, it's totally wanted to place such issues - even if I can't help here.
Can ask you, what's the general use case you like to achieve?

@guest271314
Copy link

I don't have a use case for running applications in a "sandbox".

I generally break out of sandboxes that folks try to set up.

For people interested in "sandbox" code we already have that with Worker and WebAssembly in and out of the browser and SharedWorker, Worklet interfaces in the browser.

@digipigeon
Copy link

digipigeon commented Jul 18, 2024

Runtime Limits

  1. Set Limits
    Maximum Memory
    Max CPU Time - as a decimal between 0-1 1 being its allowed to consume 100% of the core/process that it is running on.

  2. Observability
    It should be possible to poll the sandbox to find out, how much memory is being consumed (either as a value or as a percentage), same as CPU time.

  3. Informative Errors
    If the sandbox is destroyed because it exceeds the max memory or the cpu is used too much there should be a clean informative error thrown (according to the new design it might be good to throw this at both the runtime.runSandboxed level as well as at the sandbox.evalCode level.

I don't think its possible to include anything at present like the --allow-net feature of deno in node. However instead of marshaling (to and from) a fetch replacement which imposes this limitation within javascript. It would be desirable to look towards seeing if there is any way possible to impose a limitation on the sandbox runtime. If it was a separate process, there are ways to do this from the OS. But I have not found out a compatible solution for worker threads. However if there was any possible way to do this, it would be very good.

@sebastianwessel
Copy link
Owner Author

Hey @digipigeon
thanks for your feedback. There was a similar question recently Limit CPU and memory usage.
The idea of polling from outside is interesting, but there is no simple working solution for it in node. As long as the eval function is running, the host side is kind of blocked. If there is no eval executed, it is already possible to get memory information.
As the intention is, to have a highly controlled and isolated sandbox, even if it would be technically possible to allow direct net access, I don't think I will add it (at least per default).
The current focus is, to provide an environment, which is as close as possible to node and similar runtimes.

@digipigeon
Copy link

Hi @sebastianwessel, would you consider implementing https://nodejs.org/api/worker_threads.html#performanceeventlooputilizationutilization1-utilization2 as an alternative to accomplish something similar?

@sebastianwessel
Copy link
Owner Author

@digipigeon Not directly in this library, as the focus is on providing a sandbox, data (de-)serialization, runtime compatibility inside the sandbox, and developer experience (DX).

The developer should be free to choose the method that fits best. My recommendation is to use libraries that are specialized for this, such as the poolifier-web-worker package, which is used in the Server Example here.

For instance, the usage in the browser might differ from that in the backend. In the browser, you might need only one sandbox, while in the backend, as many sandboxes as possible are required.

@aashutoshrathi
Copy link

Can there be fuel metering like in wasmtime?
Since it's similar concept in terms of running JS in an isolated environment using some engine compiled to WASM

@sebastianwessel
Copy link
Owner Author

sebastianwessel commented Aug 12, 2024

@aashutoshrathi as quickly is used, there is the option to do something like this:

‘‘‘typescript
let interruptCycles = 0
runtime.setInterruptHandler(() => ++interruptCycles > 1024)

‘‘‘

@aashutoshrathi
Copy link

@sebastianwessel and I can use interruptCycles as fuel here?

@sebastianwessel
Copy link
Owner Author

Kind of - it highly depends on your use case and what you like to achieve I guess.

Personally, I do not see any real world use case, where it makes sense, to count such things, because in this case, you will need up front what is executed in the sandbox, to find the correct value.
It is simply the wrong layer to control such things imo.
When it comes to resource consumption, you probably would need to do it on the webassembly level. Meaning you would need to configure node/bun/browser to restrict the wasm resources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants