[whatwg] Workers feedback

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

On Wed, 6 Aug 2008, Aaron Boodman wrote:
> I am opposed to the utils object. I don't see any precedent for this 
> anywhere, and it just feels ugly to me. I liked it the way you had it 
> before, with these APIs in a shared base interface.

Ok. I don't have an opinion on this. Jonas?

In the absence of any arguments either way, my default would be put it all 
on the global object; clashes are manageable, the Window object does it 
that way, and there are enough things that we kinda want to put on the 
global scope anyway (the core worker stuff) that it's not a clear that the 
gain is huge.

> > I've tried to simplify the MessagePort interface as follows:
> >
> >  * messages are now queued, and won't be delivered until either the
> >    'start()' method on the port is called, or the 'onmessage' 
> >    attribute is set to some value.
> >
> >  * messages are now queued, instead of a port becoming inactive when its
> >    other side is suspended.
> Can you explain the rationale for these two changes?

It makes it a lot simpler to use. Before, you ran the risk of the port 
becoming unavailable as you posted to it, now it'll just get sent later. 
Before, you had to wait for hte onload on the port before sending 
messages, now it'll just work.

> >  * I've made the worker receive its first port as a property of the global
> >    object (port) instead of having to listen to the 'connect' event
> >    (though the connect event still fires, so you can do shared 
> >    workers).
> I liked it the way you had it, before. I'd rather the first connection 
> to a worker wasn't a special case, either for the worker or for the 
> worker's creator.

If it's not a special case, in the simple case you have to listen to an 
event just to get the port, which seems excessive. For example this in 
the old model:

   var port;
   onconnect = function (event) {
     port = event.port;

...becomes this in the current model:

   // don't have to do anything!

(It also means that workers by default have a lifetime of the creator even 
if they don't do anything. I guess we don't need this anymore given the 
new lifetime stuff, though.)

> That's also one reason why I like having a separate Worker object and 
> having the two-step process of creating the worker, then sending it a 
> message. It means that creating a new channel to a worker is always the 
> same.

It seems that designing the API to add extra steps is a bad thing 
generally speaking. :-)

> I think that 'load', 'error', and 'unload' could go on the worker. As 
> far as I can tell, the only thing 'load' and 'error' are used for is 
> telling the creator of a worker that the worker loaded or failed to 
> load. In that case, it seems wrong to throw them on MessagePort, since 
> MessagePorts are also used for many other things.
> I also still think that Workers could have their own sendMessage. The 
> messages sent to this would be delivered to the worker as 'message' 
> events targeted at WorkerGlobalObject (eliminating the need for 
> onconnect?). This would make Workers and postMessage very similar to 
> Window and postMessage, which seems nice to me.

How's this for a compromise:

We make the createWorker() methods return a Worker object, but the Worker 
object _inherits_ from MessagePort. So effectively it is a port, but we 
can move the onload and onerror stuff to the Worker object instead of 
having them on all MessagePorts.

Would that work for you?

> > The main reason I used 'unload' and 'close' is consistency with how 
> > the rest of the platform works. (With a Window, you call 
> > window.close() to invoke window.onunload.) I can change that if people 
> > want, though I do think consistency is worth keeping here.
> I think the concept of a port becoming inactive is interesting in all 
> the cases MessagePorts are used, so this should stay. In fact, should it 
> be called 'oninactive'?

Well at this point a port only becomes inactive (and fires unload) when 
the close() method is called or when the other side is owned by a document 
that gets discarded.

Incidentally, I noticed that unload isn't called when it stops being an 
active needed worker (i.e. when its users are all discarded). Should we 
fire unload in that case too? I'm thinking the "Closing orphan workers" 
step should fire unload at the worker.

> > On Mon, 4 Aug 2008, Aaron Boodman wrote:
> >>
> >> So for example, I would be for moving over a subset of the navigator and
> >> location objects as-is (these seem to work well), but against moving
> >> over the document.cookie "interface" (it works poorly).
> >
> > I agree with porting some subset of 'navigator' over, though since the
> > relevant parts of 'navigator' aren't defined even for HTML5 yet, I haven't
> > yet done this. There's an issue marker in the spec about this. What bits
> > would you like defined?
> The ones that are most often used for browser detection are most important, so:
> - appName
> - appCodeName
> - appVersion
> - platform
> - userAgent
> I know the whole business of browser detection is a big mess right now, 
> so if you're working on defining something better, I'd be open to having 
> some combination of the old navigator object and that new thing in 
> workers. But there is a lot of code that is very carefully crafted to 
> analyze the navigator object, so maybe it's best not to mess with that 
> too much.

I'll deal with this separately.

> >> - Should import() accept an array of URLs, so that the UA can fetch 
> >> them in parallel if it has the ability to do that?
> >
> > We could do that if you like. Is it needed?
> With the connection limits being upped in all the browsers, I think this 
> would be a good thing to have from the beginning.

Fair enough. Should they be run in whatever order they load in or should 
they be run in the order given on the aguments?

> On Wed, Aug 6, 2008 at 11:53 AM, Chris Prince <cprince at google.com> wrote:
> > 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.
> >
> > The 'name' option is just one such case.  Here are a few others:
> >
> >  - 'language' for non-JS workers (e.g. 'text/python' or 'application/llvm')
> >  - 'isContent' to pass a string or Blob instead of a url
> >  - 'lifetime' for running beyond the lifetime of a page
> >  - etc.
> >
> > 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.
> FWIW, Chris's suggestion is also fine with me. In general, I like
> these options objects since they are easily extensible.

The language should be done via an HTTP Content-Type. isContent can be 
done using data: URLs instead, if this is really needed. If we want to do 
something with a different lifetime I think we want to do it with a much 
clearer API entry point than an option burried in an argument.

So I'm not really convinced about this. I would be interested in other 
viewpoints, though.

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