W3C home > Mailing lists > Public > whatwg@whatwg.org > December 2009

[whatwg] Passing more than JSON data to workers

From: Jan Fabry <jan.fabry@monkeyman.be>
Date: Wed, 16 Dec 2009 22:27:28 +0100
Message-ID: <F40E1222-FD8A-4398-B6E1-DC7EEAB6B369@monkeyman.be>
On 16 Dec 2009, at 19:33, Drew Wilson wrote:

> I'm not certain what a "deep copy" of the function means - would you need to copy the entire lexical scope of the function? For example, let's say you do this:
> 
> var foo = 1;
> 
> function setFoo(val) { foo = val; }
> function getFoo() { return foo; }
> 
> worker.postMessage(setFoo);
> worker.postMessage(getFoo);
> 
> foo = 2;
> 
> Then, from worker code, I call the copy of getFoo() - what should it return (undefined? Does it pull over a copy of foo from the original lexical scope, in which case it's 1)?

In my idea, the free variables get bound at the moment you call postMessage. The worker receives two different objects, they have nothing in common.

After the first postMessage, the worker receives an object, that happens to be a function, bound to some invisible variable (similar to the "trick" to creates private variables in JS). When it is called, nothing visible happens, because the foo variable is not visible on the outside.

After the second postMessage, the worker receives a new object, also a function, bound to a variable with the value 1. If you call it, it returns 1. If I call the function that the first postMessage delivered, this does not affect the function that the second passed, since they are bound to different copies of the same origin variables, and thus in effect bound to different variables.

Image if we would create a JSONOnSteriods function. If you pass it anything that a regular JSON serializer can handle, it gives the same output (the regular serializer is recursive, so if you reverse the process, you have in effect created a deep copy). My JSONOnSteriods function would also be able to serialize functions (like you can do using setFoo.toString()), but also notice the free variables and bind them. If there is a client-side (userland?) function that would accept a function and return the names of the free variables, I think you could even simulate this in regular Javascript, but a solution in the VM would be less kludgy and probably much faster.

But please, shoot holes in my theory, because it is nothing more than that.

Greetings,

Jan Fabry

> What if foo is defined in a lexical closure that is shared by both setFoo() and getFoo() - it seems like the separate copies of setFoo() and getFoo() passed to the worker would need to reconstruct a shared closure on the worker side, which seems difficult if not impossible.
> 
> I think that some variant of data URLs and/or eval() gets you most of what you really need here without requiring extensive JS VM gymnastics.
> 
> -atw
> 
> On Wed, Dec 16, 2009 at 9:23 AM, Jan Fabry <jan.fabry at monkeyman.be> wrote:
> Hello,
> 
> Has it been considered to pass more than JSON data to workers? I could not find a rationale behind this in the FAQ, or in other places I looked. I understand the need for separation because of concurrency issues, but aren't there other ways to accomplish this?
> 
> (The following text was already posted to the forum, but "zcorpan" suggested I also post it here)
> [ http://forums.whatwg.org/viewtopic.php?t=4185 ]
> 
> I am not a Javascript VM developer, so if the following does not make sense, please don't be too hard on me. A reply of "Sorry, we thought about this longer than you did, and there are still cases where this is impossible" is perfectly valid, but the more I can learn from this conversation, the better.
> 
> Would it be possible to do a deep copy of the function (object) you pass to the the constructor? So copy everything (or mark it for copy-on-write), but remove references to DOM elements if they exist. This way, I think you can create a parallel data structure, so the original one remains untouched (avoiding concurrency issues).
> 
> The important difference between this and the usual JSON-serializing of objects that the examples talk about, is that functions can be passed through too in an easy manner. If you have to simulate this using only Javascript, you have to somehow bind the free variables, which requires some introspection, and thus is not easy (if even possible?) to simulate in "user space".
> 
> The Google Gears API seems to provide both createWorker(scriptText) and createWorkerFromUrl(scriptUrl). Why was only the URL variant retained in the Web Workers spec? With the script variant, there would have been at least a little basis for more dynamic programming.
> 
> Greetings,
> 
> Jan Fabry
> 
Received on Wednesday, 16 December 2009 13:27:28 UTC

This archive was generated by hypermail 2.3.1 : Monday, 13 April 2015 23:08:54 UTC