[whatwg] Workers feedback

Ian Hickson ian at hixie.ch
Thu Aug 7 23:10:25 PDT 2008

I've made createWorker() and createNamedWorker() return Worker objects 
with a 'port' attribute that represents the original message port.

I've removed the 'utils' object and put all the APIs back onto the global 

I've changed importScript() to importScripts() and made it take any number 
of URLs.

I've made unload be fired in a worker when the worker's lifetime expires.

On Wed, 6 Aug 2008, Chris Prince wrote:
> I'll try to write up some more detailed comments later, but for the 
> question above about a 'name' parameter and overoading:
> My current thinking is that the best API design for createWorker() is:
>    MessagePort createWorker(worker_body, [WorkerOptions])
> The reason: workers are a powerful concept, and it's very likely we'll 
> want to extend them over time.

I agree in general, but I think named workers are an important enough 
distinction that it's worth a second constructor.

> I'd say other options are likely to be just as 'important' as name, so I 
> wouldn't special-case that parameter.  A 'WorkerOptions' parameter 
> supports naming, but future expansion as well.

"name" is pretty important, I don't know of anything other than the URL of 
the script that I would say is more important.

On Thu, 7 Aug 2008, Chris Prince wrote:
> It is short-sighted to expect you can fully spec something as large as 
> workers.  This is a significant new concept, and we are only scratching 
> the surface.
> So why back ourselves into a corner?  Let's be smart about the API 
> design, and allow for future flexibility.
> I don't see any downsides to the approach outlined above.  If you have 
> something specific in mind, please let us know.

There's no downside per se, it's just not neccessary at this point. We can 
always add more arguments later, including one for a lot of optional 
parameters should we decide we need an object to do that.

On Thu, 7 Aug 2008, Jonas Sicking wrote:
>> [utils]
> I don't feel very strongly about this right now. It's something we 
> started debating at mozilla and I think we'll debate it a bit more 
> before coming to a conclusion. I'm fine with putting it in the global 
> scope for now. Sorry, i didn't mean to ask for an immediate action on 
> this yet.

You said things were urgent, I assumed I should act on all your requests. :-)

> One solution I thought about is to have a base interface such as:
> interface MessagePort {
>   void postMessage(...);
>   attribute EventListener onmessage;
>   ...
> }
> Then have
> interface Worker : MessagePort {
>    bool isShared();
>    <worker specific stuff>
> }
> interface PipePort : MessagePort {
>    attribute Window ownerWindow;
>    <Pipe specific stuff>
> }
> And then make the APIs that we want to allow passing around pipe-ends take a
> PipePort object.
> The result is basically that workers are separate objects from what's 
> returned for (new MessagePipe()).port1, but they share some API.

The problem there though is that when you receive a port, you have no idea 
if it's a port into another frame, or a port into a worker that happened 
to be created as a pipe, or a port into a worker that happened to be 
created when the worker was created. I don't see why you would ever need 
to have that distinction, either. The whole point of ports as an 
architectural concept is that they provide an opaque interface, and who 
exactly is on the other side is not something that you should need to have 
any information about.

In the design in the spec now, there's a Worker object that has 'load', 
'error', and 'unload' events on, which fire at the appropriate times in 
the lifetime of the worker, and there's a .pipe attribute that provides a 
pipe into the worker.

> [importScripts()]
> Yes. Another thing is that this function should probably return void and 
> always throw if something goes wrong. I doubt that having the server 
> return a 404 is expected enough that just returning 'false' will keep 
> the program executing fine.


On Thu, 7 Aug 2008, Jonas Sicking wrote:
> To add to the above point, while the MessagePort API currently aligns 
> with the proposed Worker API, this seems likely to change in the future, 
> for example to test if a worker is shared between multiple frames.

I don't see why we'd ever do this, but I do see other things we might want 
to do to control a worker, e.g. close it or throttle it.

> I in general am not a big fan of the MessagePort API, the whole cloning 
> and dying thing is really ugly. I don't think there is much we can do 
> about that, but because of it I think we should only use the API when 
> it's strictly needed, which seems to be only in fairly complex usecases. 

I don't really understand this concern. Why is it complex? Then again, I 
have the same reaction to your proposal for a Worker object. :-)

> Exposing a MessagePort as a permanent property, like the global 'port' 
> property, has the downside that that object can potentially die if the 
> MessagePort is ever passed through postMessage somewhere.

Do you mean that:

   var w = createWorker('worker.js');
   otherWindow.postMessage('here is the worker you asked for', w.port);
   w.port.postMessage('oh i wanted to talk to you after all');

...would fail? (It would return false from the last call.)

I don't think this is a big problem. I mean, it's like being worried that 
references into a window fail to have the right effect after the window is 
closed or navigated.

> This leaves the user with a permanent property containing a dead useless 
> object. Not exposing it as a permanent property forces things like the 
> onconnect event and returning a MessagePort from createWorker.

Do you mean on the Worker (outside) or the WorkerGlobalScope (inside)?

The current spec doesn't expose 'port' as a permanent attribute on the 
WorkerGlobalScope (inside), it's just a property added to the global 
object, it's not NoDelete or anything.

> I do sort of prefer the idea of keeping the "give me a worker that is 
> potentially shared with other windows" API separate. In fact I think we 
> should call it createSharedWorker or some such. But allowing optional 
> arguments at the end seems like a good idea. Not sure if that requires 
> specific action right now or not though.

I've renamed createNamedWorker() to createSharedWorker().

Any other objections?

Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

More information about the whatwg mailing list