I would really like this as well.
I went part of the way there with tau.alpha here
That functionality could be extracted out into a library specifically for programmatically spawning web-workers.
However, that was specifically designed to work with figwheel.main, with :none and :advanced compile modes. Haven’t tried it with shadow. I believe I’ve got it to work with vanilla cljs as well, IIRC, with different tweaks.
A comprehensive lib would work in all compile modes, in all cljs build tools, on web and node. And node is its own ball of wax.
I’m not sure, but coming up with such a lib may require agreement/coordination from cljs.main’s @dnolen, figwheel’s @bhauman and shadow’s @thheller, to ensure such a lib can depend on particular locations to draw goog, cljs, lib and app code from.
Ideally, this would work such that you could pass a root goog.module node to the spawn fn, like (web-worker/spawn {:name :monitor1 :goog-module :watch-dog-lib})
, so each worker only grabs the goog.module dep graph it needs to satisfy its logic.
I’d be down to help spec it out and implement. Node is a bit of an unknown for me though.
With regard to libraries that expose capabilities that are backed by web-workers, even when using a spawn
lib mentioned above, there are other concerns we may want to coordinate between libs to cleanly expose capabilities to all types of consumers in application code:
- Will those capabilities be consumed by the application developer in the main thread or in yet another web-worker? In another web-worker, we have the option of exposing those capabilities as synchronous calls, whereas we don’t have that luxury in the main thread.
- Are we working with persistent data-structures, js objects, or js primitives?
- How will libs and apps want to handle memory - do we serialize via postMessage or via SharedArrayBuffers(SABs)? SABs require no communication overhead and no serialization overhead for primitive data. However, postMessage can be abstracted over clusters of machines.
For instance, if we wanted to build a leaflet-cljs library (similar to leafletjs), we could probably just use primitive data for the pixels, living on a SAB shared between workers for each tile being rendered. This would be much faster than via postMessage. However, if we wanted to do the rendering of much, much larger tiles, across a farm of servers, postMessage might be preferable.
Or, what if the application requires sharing js objects and cljs data structures between workers? Should a lib abstract away the serialization strategy? Should it also provide SAB and postMessage modes, for local vs distributed (multi-machine) processing?