Re: Synchronous postMessage for Workers?

On Mon, Feb 13, 2012 at 1:44 PM, Ian Hickson <ian@hixie.ch> wrote:

> An alternative is to add continuations to the platform:
>
>   // continuation
>   // (this is not a formal proposal, just a illustration of the concept)
>   var message;
>   self.onmessage = function (event) {
>     message = event;
>     signal('got message'); // queues a task to resume from yieldUntil()
>   };
>   ...
>   yieldUntil('got message');
>   ...
>
> This would be a more general solution and would be applicable in many
> other parts of the platform. As we get more and more async APIs, I think
> it might be worth considering adding this.
>

Even better: we could design blocking APIs without having to have separate,
redundant sync and async APIs.  For example, instead of having
(hypothetically)

alert("hello"); finishedFunc(); // sync
alertAsync("hello", finishedFunc); // async

we could have a single async API,

alert("hello", finishedMessage);
yieldUntil(finishedMessage);
finishedFunc();

I suppose it's a little less pretty, and it wouldn't help with existing
APIs, but it's worth thinking about.

Anyone object to me adding something like this? Are there any better
> solutions?


This would definitely be nice to see, if it can be implemented.

This approach would also allow blocking for a message on any message port,
and not just the builtin worker ports, since it wouldn't result in
deadlock.  The failure mode would be permanently yielded, "stuck" call
stacks, where a function is waiting for a message that it'll never
receive.  But, that's inherent in this feature, since you could always
yield and then never signal.

> Should we just tell authors to get used to the async style?

One of the biggest gains of Workers, in my view, is specifically that it
allows writing code in a synchronous style.  Writing code in an async way
is fine when you really need something to run in the UI thread, but it
leads to more complex, harder to write code.  We should definitely prefer
to give robust ways to write linear, synchronous code.

If this can even be done in the UI thread, as I think what you're
suggesting would allow, that's even better.


For what it's worth, it would be nice to see this implemented in terms of
message ports.  For example, something like this:

port2.postMessage("message");
msg = yield(port1);
// msg.data == "message";

Other APIs could then signal wakeups; as a simple example (not a proposal),

alert("hello", port1);

which would send a message on port1 when it completes.  Waiting on multiple
ports would be straightforward, eg. msg = yield([port1, port2, port3]),
though MessageEvent would need a pointer back to the MessagePort so you can
tell which it came from.

-- 
Glenn Maynard

Received on Monday, 13 February 2012 21:11:24 UTC