WICG / proposals

A home for well-formed proposed incubations for the web platform. All proposals welcome.
https://wicg.io/
Other
233 stars 16 forks source link

Better Shared Memory handling #170

Open Autumnlight02 opened 2 months ago

Autumnlight02 commented 2 months ago

Introduction

There are a few use cases of the atomics API, but I assume they're too hard to work with and hurt performance. If you want to share Memories you have four options:

  1. use Atomics, but you're stuck with a byte array, and parsing data takes a lot of time.
  2. Use Shared array buffer, same issues as Atomics but updates are unpredictable.
  3. Transfer an object, Now this Object can be only used by the owner Thread.
  4. copy it to the thread, (sometimes copying the data and working with it can have the same overhead.) We need a better way of handling read-only multi-threaded data.

Use Cases (Recommended)

Examples:

  1. Website builders => In a builder you may have a large DOM and you need to run things like analysis to map out which CSS styles affect which element, where things could be converted into components etc. This would be a pure read operation where a worker reads the nested object state and sends back a report.
  2. Game Engine Path finding => If you have multiple Enemies with a Dynamic map this can be used to share the map state with all workers, and then send back only the calculated path, this way pathfinding and other things would be actually liable.
  3. Game Engine AI: You could basically have the game state as a read-only shared object and allow the AI to compose decisions depending on that and send that forward.

Goals (Optional)

  1. It needs to implement a read-only Primitive where a thread takes ownership as a writer, and all other threads are only consumers.
  2. It should dispatch an event when it's being updated or be awaitable similar to Atomics.
  3. It should implement high-level Wrappers => we should have things like an RMap, RSet, RBase, etc which behave like their normal counterpart, only with the difference that they're readable from other Threads. A proxy may be a solution as well but not preferred, since with RMap, Rset, and RBase we could expand upon and build our own classes like an NPC class to share that state or a CSS Style class for a web builder.

Non-goals (Optional)

Better data transfer between threads. Right now the prototype is lost. It would be a neat function if Workers could be assigned an array of classes that can be used to populate the prototypes on transfer via postmessage. Right now only the inbuilt Classes like Map and Set are being kept.

Proposed Solution

Implementation of new base classes which are read-only by all other workers, but only writable by a given worker which holds the "Ownership". It would include Base Classes such as RMap, RSet, RBase, etc.

Examples (Recommended)

As stated in Examples, for Game development, Website builder development (or any other kind of editor environment like Figma. It could also have use cases where a UI can be composed of multiple workers with an off-screen canvas, where all workers read the main UI state from the main thread.

Alternate Approaches (Optional)

Via Atomics and sharedArrayBuffer. The only solution I've seen there was a sharedMap which was painfully slow and used JSON stringify. When you filter for atomic.add on GitHub and filter for js + ts you only get 5 pages of results and in total 1.6K hits. This (In my humble opinion) may be an indicator that it's not well enough usable.

Privacy & Security Considerations

I assume a danger could be that people will use this more often instead of passing specifically the data on to a worker to which it should have access (you may run third-party library code in workers.)

Let’s Discuss (Optional)

Please give feedback on this.