Re: Synchronous postMessage for Workers?

2011-11-17 Thread David Levin
On Thu, Nov 17, 2011 at 6:41 PM, Jonas Sicking  wrote:

> On Thu, Nov 17, 2011 at 6:05 PM, David Levin  wrote:
> >
> >
> > On Thu, Nov 17, 2011 at 5:05 PM, Jonas Sicking  wrote:
> >>
> >> On Thu, Nov 17, 2011 at 2:07 PM, David Levin 
> wrote:
> >> > It seems like this mechanism would deadlock a worker if two workers
> send
> >> > each other a synchronous message.
> >>
> >> Indeed. We can only allow child workers to block on parent workers.
> >> Never the other way around.
> >
> > So the api would have to know who is listening to the other end of the
> port
> > and throw if it isn't a parent?
>
> I'm not convinced that we can do this with ports in a sane manner.
> Only on dedicated workers. There you always know who is listening on
> the other end. I.e. only on the DedicatedWorkerGlobalScope/Worker
> interfaces.


Ah so the proposal is really only adding a new method only
on DedicatedWorkerGlobalScope which send a synchronous message and
something corresponding on Worker which can respond to this.

This proposal as you see it does nothing for port or shared workers.

That seems to make more sense now.

dave


Re: Opening discussion on StreamWorker

2011-11-17 Thread Charles Pritchard

On 11/17/2011 4:52 PM, Charles Pritchard wrote:

Currently, Web Workers provides a "heavy" scope for multithreaded Web Apps to 
handle heavy data processing.

I'd like to draw on those specs and create a new lightweight scope useful for 
various data processing tasks typically associated with stream processing and 
GPUs.

CSS/FX is looking at custom filter tags using WebGL. I think we can implement 
these in Workers as well. The most important constraints are that the data is 
opaque: no shared storage allowed.

There are many examples of using web workers to apply effects to 32bit pixel 
data. Those could be easily applied to CSS pixel filters just as WebGL shaders 
are.

River Trail and W16 are showing us ways in which tight for loops can take 
advantage of multiple cores.

Let's look at these use cases and consider a new lightweight worker scope. 
Nothing but the bare bones, designed and expected to be used for a very 
specific type of task.

Existing CanvasPixelArray processing scripts are a great place to start. I 
suspect we'll be able to handle other cases, such as stream ciphers.

I'm still trying to bikeshed a name on this... StreamWorker, OpaqueWorker, 
SimpleWorker, DataWorker etc.


Please join me in the discussion. I think we can make rapid progress here now 
that Transferable has matured and we have two moderately-parallel JS 
implementations.



To be more clear: here is some in-the-wild code that is similar to what 
I'd expect to produce and consume with StreamWorker:

http://code.google.com/p/chromabrush/source/browse/frontend/js/filter.blur.js

Pseudo-code:
onmessage(data) { for(... data) { data[i] *= fancyness; }; 
postMessage(data); };


In doing this, could attach to CSS such as:   img { filter: 
custom(url('basicpixelworker.js')); }.


The worker may only use postMessage once, and it must send back an array 
of the same size.
There are no other options, no ways to pass a message to other contexts, 
no File or IDB or other APIs.
The concept here is to be very restrictive. That way, no data is leaked, 
and it behaves more like a WebGL shader (think GPGPU) than our existing 
web worker context.


If it's rigid, we can get very good performance, high parallelism, and 
modularity. We can also get quick implementation from vendors.

And they can decide when they want to optimize.

As a completely different use case, such a simple worker could provide 
stream encryption, or perhaps some other kind of basic but heavy number 
crunching. Since it's just a simple in-out routine, it can be highly 
optimized and easily added into API pipelines.


These workers would still be backward compatible. They could still be 
used as normal web workers. But in their more basic state, they can be 
more lightweight, there are no side effects

and so they are more appropriate for massive parallelism.

-Charles



Re: Synchronous postMessage for Workers?

2011-11-17 Thread Glenn Maynard
On Thu, Nov 17, 2011 at 8:05 PM, Jonas Sicking  wrote:

> On Thu, Nov 17, 2011 at 2:07 PM, David Levin  wrote:
> > It seems like this mechanism would deadlock a worker if two workers send
> > each other a synchronous message.
>
> Indeed. We can only allow child workers to block on parent workers.
> Never the other way around.
>

Note that the port entangled with the port you're waiting on might be
transferred between workers while you're waiting on it, changing hands from
a parent worker to a child worker.  It might be a valid port to block on
when you make the call, and stop being valid later.

I'm still thinking about this, but one note is that this isn't needed for
the polling case (where timeout is 0).

-- 
Glenn Maynard


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Charles Pritchard




On Nov 17, 2011, at 6:41 PM, Jonas Sicking  wrote:

> On Thu, Nov 17, 2011 at 6:05 PM, David Levin  wrote:
>> 
>> 
>> On Thu, Nov 17, 2011 at 5:05 PM, Jonas Sicking  wrote:
>>> 
>>> On Thu, Nov 17, 2011 at 2:07 PM, David Levin  wrote:
 It seems like this mechanism would deadlock a worker if two workers send
 each other a synchronous message.
>>> 
>>> Indeed. We can only allow child workers to block on parent workers.
>>> Never the other way around.
>> 
>> So the api would have to know who is listening to the other end of the port
>> and throw if it isn't a parent?
> 
> I'm not convinced that we can do this with ports in a sane manner.
> Only on dedicated workers. There you always know who is listening on
> the other end. I.e. only on the DedicatedWorkerGlobalScope/Worker
> interfaces.

I agree on this one. A big no-thanks to synchronous messaging over ports.

Still, dedicated workers to a parent seems doable.

I've proposed a different worker scope for lightweight threads. Dedicated 
workers are relatively heavy and so a few workers blocked on the parent is not 
outside of acceptability.

-Charles


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Jonas Sicking
On Thu, Nov 17, 2011 at 6:05 PM, David Levin  wrote:
>
>
> On Thu, Nov 17, 2011 at 5:05 PM, Jonas Sicking  wrote:
>>
>> On Thu, Nov 17, 2011 at 2:07 PM, David Levin  wrote:
>> > It seems like this mechanism would deadlock a worker if two workers send
>> > each other a synchronous message.
>>
>> Indeed. We can only allow child workers to block on parent workers.
>> Never the other way around.
>
> So the api would have to know who is listening to the other end of the port
> and throw if it isn't a parent?

I'm not convinced that we can do this with ports in a sane manner.
Only on dedicated workers. There you always know who is listening on
the other end. I.e. only on the DedicatedWorkerGlobalScope/Worker
interfaces.

/ Jonas



Re: Synchronous postMessage for Workers?

2011-11-17 Thread David Levin
On Thu, Nov 17, 2011 at 5:05 PM, Jonas Sicking  wrote:

> On Thu, Nov 17, 2011 at 2:07 PM, David Levin  wrote:
> > It seems like this mechanism would deadlock a worker if two workers send
> > each other a synchronous message.
>
> Indeed. We can only allow child workers to block on parent workers.
> Never the other way around.
>

So the api would have to know who is listening to the other end of the port
and throw if it isn't a parent?

dave


Re: Web Messaging Intents, was: Re: [DRAFT] Web Intents Task Force Charter

2011-11-17 Thread Greg Billock
On Mon, Nov 14, 2011 at 7:24 PM, Charles Pritchard  wrote:

> **
> Does anybody use registerProtocolHandler in any real sense? Is
> registerContentHandler needed? It seems like Web Intents is an evolution on
> the concept. I don't think we're going to see convergence on those old
> methods. I'm ready to leave them both in favor of a yet-to-be announced
> candidate (web intents).
>
> URIs are better than protocols,  and Intents are better than content
> handlers. In my opinion.
>

RPH seems to be intended primarily for mailto: (I think that's where it is
used.) I'm not sure what the RCH usage is like. It is definitely possible
to imagine mapping UA handling of mailto: onto web intents. The way I think
of it is like this: RPH is basically an action with a payload. RCH is
essentially type info with the payload. Web Intents is kind of off-axis
with both an action and a type as well as the payload. The idea (taking
inspiration from the pluggable usage in the Android ecosystem) is that the
action (analogous to the "protocol") is a locus between the client and
handling service which can be messaged to the user in a well-understood
way. (i.e. instead of just saying "here's some data, do whatever you want
with it," which is a more content-type-driven


As far as I can tell, the model doesn't prohibit, nor does it encourage,
> the passing of MessageChannel.
> It's very much made for an RPC style of communication, but if the message
> being passed back is a channel, well that's just fine.
>
> Am I mistaken? What I'm seeing is that we get MessageChannel for free, and
> there's no need to specify further.
> Individual Intent authors can do that themselves.
>


Yes. We envision RPC-style request/response as the sweet spot for intents.
We've definitely considered use cases which are better served by opening a
persistent channel. It isn't clear to me as yet what to do about those.
They definitely imply a more well-specified protocol to be pursued over
that channel. Web Intents as an API doesn't really include or exclude that
in the current form.

On the other hand, it'd be a really nice application of the Web Intents
permissions mechanism to be able to connect up, say, an SSH connection
using Web Intents, so that I could write an in-browser terminal which could
then be attached to a secure socket by the user.

At this point, I'm not sure whether this kind of persistent connection use
case is far enough from Web Intents to want to exclude it, or close enough
to want to include it explicitly. Our early belief is that we aren't ruling
it out with the proposed API, since MessageChannels could be provided or
returned in the payload data. On the other hand, we haven't chosen to
explicitly include such usage.

But a lot of this stuff just comes with nice platform integration; I just
tried passing Blob objects through intents in Chrome Tip-of-Tree with our
prototype, and it Just Works, allowing a really appealing vision into what
"upload" intents and file interactions could be like. Wins like that make
me think that focusing on the sweet spot RPC interaction will not paint us
into a corner.

-Greg


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Jonas Sicking
On Thu, Nov 17, 2011 at 2:07 PM, David Levin  wrote:
> It seems like this mechanism would deadlock a worker if two workers send
> each other a synchronous message.

Indeed. We can only allow child workers to block on parent workers.
Never the other way around.

I think in theory it would be possible to reverse the direction for
given parent/child pairs, but I'm not yet sure that that couldn't lead
to deadlocks. And I'm definitely not sure it's worth the complexity.

/ Jonas



Opening discussion on StreamWorker

2011-11-17 Thread Charles Pritchard
Currently, Web Workers provides a "heavy" scope for multithreaded Web Apps to 
handle heavy data processing.

I'd like to draw on those specs and create a new lightweight scope useful for 
various data processing tasks typically associated with stream processing and 
GPUs.

CSS/FX is looking at custom filter tags using WebGL. I think we can implement 
these in Workers as well. The most important constraints are that the data is 
opaque: no shared storage allowed.

There are many examples of using web workers to apply effects to 32bit pixel 
data. Those could be easily applied to CSS pixel filters just as WebGL shaders 
are.

River Trail and W16 are showing us ways in which tight for loops can take 
advantage of multiple cores.

Let's look at these use cases and consider a new lightweight worker scope. 
Nothing but the bare bones, designed and expected to be used for a very 
specific type of task.

Existing CanvasPixelArray processing scripts are a great place to start. I 
suspect we'll be able to handle other cases, such as stream ciphers.

I'm still trying to bikeshed a name on this... StreamWorker, OpaqueWorker, 
SimpleWorker, DataWorker etc.


Please join me in the discussion. I think we can make rapid progress here now 
that Transferable has matured and we have two moderately-parallel JS 
implementations.


-Charles




Re: Synchronous postMessage for Workers?

2011-11-17 Thread Rick Waldron
On Thu, Nov 17, 2011 at 6:50 PM, Glenn Maynard  wrote:

> On Thu, Nov 17, 2011 at 6:17 PM, Rick Waldron wrote:
>
>> No, it's not. Messaging should not block either process.
>>
>
> No, it's perfectly fine to block a worker, as long as the worker
> explicitly requests it and is expecting it.
>
> I don't know what that means.  Synchronous APIs are one of the major
>> reasons to have Workers in the first place.
>>
>> Considering the current messaging API and the allowed host APIs, I
>> strongly disagree.
>>
>
> I'm not quite sure what you mean by "allowed host APIs", but there are
> lots of synchronous APIs in Workers: File API, Filesystem API, IndexedDB.
> These are all new APIs, not historical accidents (like sync XHR in the UI
> thread).  Synchronous (blocking) APIs in workers is entirely by design, in
> order to allow writing clean, linear code instead of code that has to yield
> to the calling environment all the time.
>

Sorry, I should've been clearer - I was referring to the renderer-to-worker
messaging API - all event based, all async.

TBH, at this point I'd be more interested in an actual prototype
implementation to see the effects it would have on Worker to Worker
messaging, SharedWorker etc.

Rick




> --
> Glenn Maynard
>
>


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Glenn Maynard
On Thu, Nov 17, 2011 at 6:17 PM, Rick Waldron wrote:

> No, it's not. Messaging should not block either process.
>

No, it's perfectly fine to block a worker, as long as the worker explicitly
requests it and is expecting it.

I don't know what that means.  Synchronous APIs are one of the major
> reasons to have Workers in the first place.
>
> Considering the current messaging API and the allowed host APIs, I
> strongly disagree.
>

I'm not quite sure what you mean by "allowed host APIs", but there are lots
of synchronous APIs in Workers: File API, Filesystem API, IndexedDB.  These
are all new APIs, not historical accidents (like sync XHR in the UI
thread).  Synchronous (blocking) APIs in workers is entirely by design, in
order to allow writing clean, linear code instead of code that has to yield
to the calling environment all the time.

-- 
Glenn Maynard


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Rick Waldron


On Nov 17, 2011, at 2:37 PM, Glenn Maynard  wrote:

> On Thu, Nov 17, 2011 at 2:16 PM, Rick Waldron  wrote:
> This is counter to the whole premise of Workers, which should be independent 
> of their renderer process and certainly not block themselves while waiting 
> for responses from the renderer (which inherently describes an async 
> behaviour). 
> 
> That's backwards.  The premise is that the renderer (UI) will not be blocked 
> by workers, not that workers won't be blocked by the renderer.

No, it's not. Messaging should not block either process. 

> 
> > Sync apis are sore thumb in GlobalWorkerScope's world.
> 
> I don't know what that means.  Synchronous APIs are one of the major reasons 
> to have Workers in the first place.

Considering the current messaging API and the allowed host APIs, I strongly 
disagree. 



> 
> -- 
> Glenn Maynard
> 


Re: Synchronous postMessage for Workers?

2011-11-17 Thread David Levin
It seems like this mechanism would deadlock a worker if two workers send
each other a synchronous message.

dave


On Thu, Nov 17, 2011 at 10:37 AM, Joshua Bell  wrote:

> Jonas and I were having an offline discussing regarding the synchronous
> Indexed Database API and noting how clean and straightforward it will allow
> Worker scripts to be. One general Worker issue we noted - independent of
> IDB - was that there are cases where Worker scripts may need to fetch data
> from the Window. This can be done today using bidirectional postMessage,
> but of course this requires the Worker to then be coded in now common
> asynchronous JavaScript fashion, with either a tangled mess of callbacks or
> some sort of Promises/Futures library, which removes some of the benefits
> of introducing sync APIs to Workers in the first place.
>
> Wouldn't it be lovely if the Worker script could simply make a synchronous
> call to fetch data from the Window?
>
> GTNW.prototype.end = function () {
> var result = self.sendMessage({action: "prompt_user", prompt: "How
> about a nice game of chess?"});
> if (result) { chess_game.begin(); }
> }
>
> The requirement would be that the Window side is asynchronous (of course).
> Continuing the silly example above, the Window script responds to the
> message by fetching some new HTML UI via async XHR, adding it to the DOM,
> and only after user input and validation events is a response sent back to
> the Worker, which proceeds merrily on its way.
>
> I don't have a specific API suggestion in mind. On the Worker side it
> should take the form of a single blocking call taking the data to be passed
> and possibly a timeout, and allowing a return value (on
> timeout return undefined or throw?). On the Window side it could be a new
> event on Worker which delivers a "Promise" type object which the Window
> script can later fulfill (or break). Behavior on multiple event listeners
> would need to be defined (all get the same "Promise", first "fulfill" wins,
> others throw?).
>
>


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Glenn Maynard
On Thu, Nov 17, 2011 at 3:47 PM, Joshua Bell  wrote:

> ^^^ Nit: That would revert back to being postMessage(), no new API on the
> Worker side.
>

Right, I just copied your example.  (You mean "no new API for sending
messages"--the "get the next event" method would be new API for workers.)

One concern with this overall approach is that any pending message would be
> grabbed, not just one intended as a response.
>

You just create separate MessagePorts to segregate different types of
messages.  messagePort.getMessageIfExists would only retrieve messages on
messagePort.

"Retrieve the first message from a list of message ports", akin to
poll/select, may also be useful, eg. getFirstMessage([port1, port2],
timeout).  I'm not sure if there are use cases for this, but it's worth
mentioning.

I agree that "return" makes more sense than "dispatch", since we're
> introducing this to support a linear programming style. On the other hand,
> you could emulate "return" with "dispatch" via helper functions that swap
> in a temporary onmessage handler (a variant on your
> getPendingMessageWithoutDelivery example in the older thread)
>

Right, you can emulate either using the other.  Alternatively, do both:
fire the event synchronously, then return it.

-- 
Glenn Maynard


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Joshua Bell
On Thu, Nov 17, 2011 at 11:28 AM, Glenn Maynard  wrote:

>
> We discussed a very similar thing about a year ago; I've been meaning to
> bring that up again, so this is probably as good a time as any.
> http://lists.w3.org/Archives/Public/public-webapps/2010OctDec/1075.html
>

Ah, thanks - I should have gone digging.


> The proposal is to allow polling a MessagePort, causing the first queued
> message, if any, to be dispatched (or alternatively, to be returned).  This
> could be easily extended to handle the above, by adding a "blocking
> duration" parameter.
>
> For example, working from Jonas's getMessageIfExists proposal:
>
>
>   self.sendMessage({action: "prompt_user", prompt: "How about a nice game
> of chess?"});
>
^^^ Nit: That would revert back to being postMessage(), no new API on the
Worker side.


>   var msg = messagePort.getMessageIfExists(5.0);
>   if(msg && msg.data) { chess_game.begin(); }
>
> Here, 5.0 means to block for five seconds (with a sentinel like -1 would
> mean "block forever"), and the return value is the MessageEvent, returning
> null if no message is received.
>

One concern with this overall approach is that any pending message would be
grabbed, not just one intended as a response. But we're talking about
workers that are intending to run long-lived functions here anyway so they
must explicitly block/poll to receive any communication. It's a more
complicated model for developers, but the complexity is opt-in. So I
like it.

I preferred the "dispatch the first message" approach before, but your
> blocking use case may make the "return the first message" approach better.
>

I agree that "return" makes more sense than "dispatch", since we're
introducing this to support a linear programming style. On the other hand,
you could emulate "return" with "dispatch" via helper functions that swap
in a temporary onmessage handler (a variant on your
getPendingMessageWithoutDelivery example in the older thread)


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Glenn Maynard
On Thu, Nov 17, 2011 at 2:16 PM, Rick Waldron wrote:

> This is counter to the whole premise of Workers, which should be
> independent of their renderer process and certainly not block themselves
> while waiting for responses from the renderer (which inherently describes
> an async behaviour).
>

That's backwards.  The premise is that the renderer (UI) will not be
blocked by workers, not that workers won't be blocked by the renderer.

> Sync apis are sore thumb in GlobalWorkerScope's world.

I don't know what that means.  Synchronous APIs are one of the major
reasons to have Workers in the first place.

-- 
Glenn Maynard


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Glenn Maynard
On Thu, Nov 17, 2011 at 1:37 PM, Joshua Bell  wrote:

> Jonas and I were having an offline discussing regarding the synchronous
> Indexed Database API and noting how clean and straightforward it will allow
> Worker scripts to be. One general Worker issue we noted - independent of
> IDB - was that there are cases where Worker scripts may need to fetch data
> from the Window. This can be done today using bidirectional postMessage,
> but of course this requires the Worker to then be coded in now common
> asynchronous JavaScript fashion, with either a tangled mess of callbacks or
> some sort of Promises/Futures library, which removes some of the benefits
> of introducing sync APIs to Workers in the first place.
>
> Wouldn't it be lovely if the Worker script could simply make a synchronous
> call to fetch data from the Window?
>
> GTNW.prototype.end = function () {
> var result = self.sendMessage({action: "prompt_user", prompt: "How
> about a nice game of chess?"});
> if (result) { chess_game.begin(); }
> }
>

We discussed a very similar thing about a year ago; I've been meaning to
bring that up again, so this is probably as good a time as any.
http://lists.w3.org/Archives/Public/public-webapps/2010OctDec/1075.html

The proposal is to allow polling a MessagePort, causing the first queued
message, if any, to be dispatched (or alternatively, to be returned).  This
could be easily extended to handle the above, by adding a "blocking
duration" parameter.

For example, working from Jonas's getMessageIfExists proposal:

  self.sendMessage({action: "prompt_user", prompt: "How about a nice game
of chess?"});
  var msg = messagePort.getMessageIfExists(5.0);
  if(msg && msg.data) { chess_game.begin(); }

Here, 5.0 means to block for five seconds (with a sentinel like -1 would
mean "block forever"), and the return value is the MessageEvent, returning
null if no message is received.

I preferred the "dispatch the first message" approach before, but your
blocking use case may make the "return the first message" approach better.

I think this is a fundamental missing piece to worker communication.  A
basic reason for having Workers in the first place is so you can write
linear code, instead of having to structure code to be able to return
regularly (often awkward and inconvenient), but currently in order to
receive messages in workers you still have to do that.

The use case that lead me to this initially was wanting to cancel
operations cleanly, without having to terminate and reinitialize the worker
entirely, eg. for input completion where processing restarts on each
keypress.  (That was an issue because the completion was initialized from
localStorage, making startup expensive; IndexedDB will help that particular
example, but this applies to any worker with nontrivial startup times.)

-- 
Glenn Maynard


Re: Synchronous postMessage for Workers?

2011-11-17 Thread Rick Waldron
On Thu, Nov 17, 2011 at 1:37 PM, Joshua Bell  wrote:

> Jonas and I were having an offline discussing regarding the synchronous
> Indexed Database API and noting how clean and straightforward it will allow
> Worker scripts to be. One general Worker issue we noted - independent of
> IDB - was that there are cases where Worker scripts may need to fetch data
> from the Window. This can be done today using bidirectional postMessage,
> but of course this requires the Worker to then be coded in now common
> asynchronous JavaScript fashion, with either a tangled mess of callbacks or
> some sort of Promises/Futures library, which removes some of the benefits
> of introducing sync APIs to Workers in the first place.


Workers are suited quite well to Promises/Futures apis. Sync apis are sore
thumb in GlobalWorkerScope's world.


>
> Wouldn't it be lovely if the Worker script could simply make a synchronous
> call to fetch data from the Window?
>
> GTNW.prototype.end = function () {
> var result = self.sendMessage({action: "prompt_user", prompt: "How
> about a nice game of chess?"});
> if (result) { chess_game.begin(); }
> }
>
> The requirement would be that the Window side is asynchronous (of course).
> Continuing the silly example above, the Window script responds to the
> message by fetching some new HTML UI via async XHR, adding it to the DOM,
> and only after user input and validation events is a response sent back to
> the Worker, which proceeds merrily on its way.
>
> I don't have a specific API suggestion in mind. On the Worker side it
> should take the form of a single blocking call taking the data to be passed
> and possibly a timeout, and allowing a return value (on
> timeout return undefined or throw?).
>

This is counter to the whole premise of Workers, which should be
independent of their renderer process and certainly not block themselves
while waiting for responses from the renderer (which inherently describes
an async behaviour).



> On the Window side it could be a new event on Worker which delivers a
> "Promise" type object which the Window script can later fulfill (or break).
> Behavior on multiple event listeners would need to be defined (all get the
> same "Promise", first "fulfill" wins, others throw?).
>
>

Rick


Synchronous postMessage for Workers?

2011-11-17 Thread Joshua Bell
Jonas and I were having an offline discussing regarding the synchronous
Indexed Database API and noting how clean and straightforward it will allow
Worker scripts to be. One general Worker issue we noted - independent of
IDB - was that there are cases where Worker scripts may need to fetch data
from the Window. This can be done today using bidirectional postMessage,
but of course this requires the Worker to then be coded in now common
asynchronous JavaScript fashion, with either a tangled mess of callbacks or
some sort of Promises/Futures library, which removes some of the benefits
of introducing sync APIs to Workers in the first place.

Wouldn't it be lovely if the Worker script could simply make a synchronous
call to fetch data from the Window?

GTNW.prototype.end = function () {
var result = self.sendMessage({action: "prompt_user", prompt: "How
about a nice game of chess?"});
if (result) { chess_game.begin(); }
}

The requirement would be that the Window side is asynchronous (of course).
Continuing the silly example above, the Window script responds to the
message by fetching some new HTML UI via async XHR, adding it to the DOM,
and only after user input and validation events is a response sent back to
the Worker, which proceeds merrily on its way.

I don't have a specific API suggestion in mind. On the Worker side it
should take the form of a single blocking call taking the data to be passed
and possibly a timeout, and allowing a return value (on
timeout return undefined or throw?). On the Window side it could be a new
event on Worker which delivers a "Promise" type object which the Window
script can later fulfill (or break). Behavior on multiple event listeners
would need to be defined (all get the same "Promise", first "fulfill" wins,
others throw?).