[whatwg] Web Workers feedback

Ian Hickson ian at hixie.ch
Fri Apr 16 18:06:05 PDT 2010

On Tue, 30 Mar 2010, Jonas Sicking wrote:
> >
> > My understanding was that relying on exceptions for non-exceptional 
> > cases is bad API design. Why would it be ok here?
> I think fallback is to be considered an exceptional case. Especially as 
> time goes on and more browsers implement support for the new type.
> > The question is, what are the actual concrete cases where people will 
> > be sending DOM nodes? Without concrete cases, it's easy to construct 
> > artificial cases that prove this to be better one way or the other.
> Say sending a DOM that the user has edited (using contentEditable) which 
> the worker will convert into a ODF document and send to the server.
> >> Personally, I think throwing an exception fits in with the spec's use 
> >> of them elsewhere (i.e., cross-document and web workers.)
> >
> > Where do we use exceptions for extension points in a similar way?
> For circular object graphs in the very same algorithms.

On Thu, 1 Apr 2010, Simon Pieters wrote:
> It does matter because if you send null, the worker has to respond that 
> it got null so the script can do what it wants on the main thread, which 
> makes the operation async and means the worker script needs logic for 
> the non-supported case. It's more convenient to catch an exception and 
> do what you want directly, and have the worker script only care about 
> the supported case.
> This is actually the exact same problem as what we have now, moving from 
> string based to structured clone. In order to test structured clone 
> support, you have to send a message back and forth. I think it would 
> have been better if non-strings threw an exception from the start, but 
> it's too late to change it now.
> A use case I had with structured clone is posting three ImageData 
> objects where the worker compares the pixels of two of them and puts the 
> difference on the third and posts that one back. I do it in a worker 
> because it's a heavy operation for big images and I needed to keep the 
> timing correct for events in the main thread. If workers isn't 
> supported, I did the operation later when the timing of events didn't 
> matter. I didn't make it detect support for workers but lack of 
> structured clone because it seemed too annoying to implement.

Fair enough. I've changed the cloning mechanism to throw an exception 
instead of nulling host objects.

On Tue, 30 Mar 2010, Dmitry Titov wrote:
> [...] close() method on WorkerGlobalScope.
> In particular, the spec seems to imply that after calling close() inside 
> the worker, the JS does not get terminated right away, but rather 
> continues to execute, while an internal 'closing' flag is set and a 
> message queue associated with the worker discards all the tasks, 
> existing and future. Also, all ports are immediately disentangled.

I've changed the spec based no the feedback below so that the ports are no 
longer disentangled upon calling close().

> This seems to leave some questions without explicit answer, with 
> differences in current implementations:
> 1. Does this code in a worker continues looping until the parent page
> unloads:
>  ...
>  close();
>  while(true) {}
> WebKit V8 terminates, WebKit JCS terminates after a timeout, FF does not 
> terminate.

FF is correct. The WebKits are not non-conforming, though, since you're 
basically allowed to kill workers whenver.

> 2. Do the errors propagate back to Worker object after close()?
> ...
> close();
> nonExistingFunction();  <<-- throws, if not processed locally, posts error
> info to the Worker object.
> In WebKit and FF errors propagate, although it does not seem consistent
> while worker closed all the ports and is in a dormant state.

The spec seems clear that close() has no effect on error propagation.

> 3. Should synchronous operations work after close()? Asynchronous ones
> perhaps should not, because of the event loop queue which is stopped...
> ...
> close();
> xhr.open("GET", "foo.com", *false*);
> xhr.send();
> WebKit: does not work (mostly), FF - does work.

Anything depending on tasks doesn't work. Sync XHR doesn't seem to use the 
event loop mechanism, so it's ok.

> Perhaps it would be simpler to either say nothing is executed/posted/fired
> after close() (immediate termination), or to enable worker run unimpeded
> (with ports open, etc) until it naturally yields from JS.

I've gone with the latter.

On Tue, 30 Mar 2010, Drew Wilson wrote:
> I'll note that the spec gives the UA an significant amount of latitude 
> about its behavior after close() is called:
> User agents may invoke the "kill a worker <#kill-a-worker>" processing 
> model on a worker at any time, e.g. in response to user requests, in 
> response to CPU quota management, or when a worker stops being an active 
> needed worker<#active-needed-worker> if the worker continues executing 
> even after its closing<#dom-workerglobalscope-closing> flag was set to 
> true.
> Essentially, UAs can kill a worker at any time, and since the "kill a 
> worker" algorithm allows UAs to abort the script after a 
> user-agent-defined amount of time (including zero), it seems like almost 
> any behavior post-close is compliant. This seems like a guaranteed 
> source of cross-browser incompatibilities.

It also allows killing scripts pre-close. We don't really have much choice 
here; browsers need to be able to terminate any malware or runaway 
process at their whim, basically.

> I've always operated under the impression that the intent of the spec is 
> to allow pending worker operations to complete, but still give UAs the 
> ability to abort scripts that don't exit in a timely manner (so close() 
> should not immediately abort the script), but I don't see anything in 
> the spec regarding this.

This is what the spec now requires, modulo UAs being allowed to bail on 
worker scripts at any time.

> For #2 [above], I believe that exceptions in worker context should 
> *always* be reported, regardless of closing state. Section 4.6 (Runtime 
> script errors) makes no mention of tying this behavior to the closing 
> flag.


On Tue, 30 Mar 2010, Dmitry Titov wrote:
> But if we say close() lets script run until completion (but prevents 
> further messages/events from dispatching), then perhaps we don't need it 
> at all - there is nothing then that script in the worker can not do to 
> the same effect (unregister onmessage, clear timers etc).

It can be a lot harder to actually find all the various things that are 
keeping a worker alive than just to call close().

> That means letting worker to call close() on itself only makes 
> additional sense if it is specified as immediate termination. It could 
> be useful and it can be specified in deterministic manner.

I agree that immediate termination might also be useful, but if that's 
what you want, just don't do anything after calling close(). :-)

On Thu, 1 Apr 2010, Jonas Sicking wrote:
> The one thing that we do and that is somewhat iffy is the close event. 

The close event is no longer in the spec, so at this point it's a Firefox 
proprietary feature. :-) We removed it to prevent exposing GC behaviour, 
because otherwise if pages start depending on one particular behaviour, 
we'll have accidentally forced the GC rules into the platform, which 
seems like an incredibly bad idea.

> [...] it exposes GC behavior. This is very unfortunate indeed and 
> because of it I feel that our implementation is somewhat experimental.

I would recommend dropping the 'close' event for this reason.

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