FYI: as of now, WebKit Workers &#39;close()&#39; behavior is following the results of this thread and is compatible with FF (except we don&#39;t implement close event, as mentioned here).<br><br><div>Thanks for clarifications!</div>
<div><br></div><div>Dmitry</div><div><br><div class="gmail_quote">On Fri, Apr 16, 2010 at 6:06 PM, Ian Hickson <span dir="ltr">&lt;<a href="mailto:ian@hixie.ch">ian@hixie.ch</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
On Tue, 30 Mar 2010, Jonas Sicking wrote:<br>
&gt; &gt;<br>
&gt; &gt; My understanding was that relying on exceptions for non-exceptional<br>
&gt; &gt; cases is bad API design. Why would it be ok here?<br>
&gt;<br>
&gt; I think fallback is to be considered an exceptional case. Especially as<br>
&gt; time goes on and more browsers implement support for the new type.<br>
&gt;<br>
&gt; &gt; The question is, what are the actual concrete cases where people will<br>
&gt; &gt; be sending DOM nodes? Without concrete cases, it&#39;s easy to construct<br>
&gt; &gt; artificial cases that prove this to be better one way or the other.<br>
&gt;<br>
&gt; Say sending a DOM that the user has edited (using contentEditable) which<br>
&gt; the worker will convert into a ODF document and send to the server.<br>
&gt;<br>
&gt; &gt;&gt; Personally, I think throwing an exception fits in with the spec&#39;s use<br>
&gt; &gt;&gt; of them elsewhere (i.e., cross-document and web workers.)<br>
&gt; &gt;<br>
&gt; &gt; Where do we use exceptions for extension points in a similar way?<br>
&gt;<br>
&gt; For circular object graphs in the very same algorithms.<br>
<br>
On Thu, 1 Apr 2010, Simon Pieters wrote:<br>
&gt;<br>
&gt; It does matter because if you send null, the worker has to respond that<br>
&gt; it got null so the script can do what it wants on the main thread, which<br>
&gt; makes the operation async and means the worker script needs logic for<br>
&gt; the non-supported case. It&#39;s more convenient to catch an exception and<br>
&gt; do what you want directly, and have the worker script only care about<br>
&gt; the supported case.<br>
&gt;<br>
&gt; This is actually the exact same problem as what we have now, moving from<br>
&gt; string based to structured clone. In order to test structured clone<br>
&gt; support, you have to send a message back and forth. I think it would<br>
&gt; have been better if non-strings threw an exception from the start, but<br>
&gt; it&#39;s too late to change it now.<br>
&gt;<br>
&gt; A use case I had with structured clone is posting three ImageData<br>
&gt; objects where the worker compares the pixels of two of them and puts the<br>
&gt; difference on the third and posts that one back. I do it in a worker<br>
&gt; because it&#39;s a heavy operation for big images and I needed to keep the<br>
&gt; timing correct for events in the main thread. If workers isn&#39;t<br>
&gt; supported, I did the operation later when the timing of events didn&#39;t<br>
&gt; matter. I didn&#39;t make it detect support for workers but lack of<br>
&gt; structured clone because it seemed too annoying to implement.<br>
<br>
Fair enough. I&#39;ve changed the cloning mechanism to throw an exception<br>
instead of nulling host objects.<br>
<br>
<br>
On Tue, 30 Mar 2010, Dmitry Titov wrote:<br>
&gt;<br>
&gt; [...] close() method on WorkerGlobalScope.<br>
&gt;<br>
&gt; In particular, the spec seems to imply that after calling close() inside<br>
&gt; the worker, the JS does not get terminated right away, but rather<br>
&gt; continues to execute, while an internal &#39;closing&#39; flag is set and a<br>
&gt; message queue associated with the worker discards all the tasks,<br>
&gt; existing and future. Also, all ports are immediately disentangled.<br>
<br>
I&#39;ve changed the spec based no the feedback below so that the ports are no<br>
longer disentangled upon calling close().<br>
<br>
<br>
&gt; This seems to leave some questions without explicit answer, with<br>
&gt; differences in current implementations:<br>
&gt;<br>
&gt; 1. Does this code in a worker continues looping until the parent page<br>
&gt; unloads:<br>
&gt;  ...<br>
&gt;  close();<br>
&gt;  while(true) {}<br>
&gt;<br>
&gt; WebKit V8 terminates, WebKit JCS terminates after a timeout, FF does not<br>
&gt; terminate.<br>
<br>
FF is correct. The WebKits are not non-conforming, though, since you&#39;re<br>
basically allowed to kill workers whenver.<br>
<br>
<br>
&gt; 2. Do the errors propagate back to Worker object after close()?<br>
&gt; ...<br>
&gt; close();<br>
&gt; nonExistingFunction();  &lt;&lt;-- throws, if not processed locally, posts error<br>
&gt; info to the Worker object.<br>
&gt;<br>
&gt; In WebKit and FF errors propagate, although it does not seem consistent<br>
&gt; while worker closed all the ports and is in a dormant state.<br>
<br>
The spec seems clear that close() has no effect on error propagation.<br>
<br>
<br>
&gt; 3. Should synchronous operations work after close()? Asynchronous ones<br>
&gt; perhaps should not, because of the event loop queue which is stopped...<br>
&gt; ...<br>
&gt; close();<br>
&gt; xhr.open(&quot;GET&quot;, &quot;<a href="http://foo.com" target="_blank">foo.com</a>&quot;, *false*);<br>
&gt; xhr.send();<br>
&gt;<br>
&gt; WebKit: does not work (mostly), FF - does work.<br>
<br>
Anything depending on tasks doesn&#39;t work. Sync XHR doesn&#39;t seem to use the<br>
event loop mechanism, so it&#39;s ok.<br>
<br>
<br>
&gt; Perhaps it would be simpler to either say nothing is executed/posted/fired<br>
&gt; after close() (immediate termination), or to enable worker run unimpeded<br>
&gt; (with ports open, etc) until it naturally yields from JS.<br>
<br>
I&#39;ve gone with the latter.<br>
<br>
<br>
On Tue, 30 Mar 2010, Drew Wilson wrote:<br>
&gt;<br>
&gt; I&#39;ll note that the spec gives the UA an significant amount of latitude<br>
&gt; about its behavior after close() is called:<br>
&gt;<br>
&gt; User agents may invoke the &quot;kill a worker &lt;#kill-a-worker&gt;&quot; processing<br>
&gt; model on a worker at any time, e.g. in response to user requests, in<br>
&gt; response to CPU quota management, or when a worker stops being an active<br>
&gt; needed worker&lt;#active-needed-worker&gt; if the worker continues executing<br>
&gt; even after its closing&lt;#dom-workerglobalscope-closing&gt; flag was set to<br>
&gt; true.<br>
&gt;<br>
&gt; Essentially, UAs can kill a worker at any time, and since the &quot;kill a<br>
&gt; worker&quot; algorithm allows UAs to abort the script after a<br>
&gt; user-agent-defined amount of time (including zero), it seems like almost<br>
&gt; any behavior post-close is compliant. This seems like a guaranteed<br>
&gt; source of cross-browser incompatibilities.<br>
<br>
It also allows killing scripts pre-close. We don&#39;t really have much choice<br>
here; browsers need to be able to terminate any malware or runaway<br>
process at their whim, basically.<br>
<br>
<br>
&gt; I&#39;ve always operated under the impression that the intent of the spec is<br>
&gt; to allow pending worker operations to complete, but still give UAs the<br>
&gt; ability to abort scripts that don&#39;t exit in a timely manner (so close()<br>
&gt; should not immediately abort the script), but I don&#39;t see anything in<br>
&gt; the spec regarding this.<br>
<br>
This is what the spec now requires, modulo UAs being allowed to bail on<br>
worker scripts at any time.<br>
<br>
<br>
&gt; For #2 [above], I believe that exceptions in worker context should<br>
&gt; *always* be reported, regardless of closing state. Section 4.6 (Runtime<br>
&gt; script errors) makes no mention of tying this behavior to the closing<br>
&gt; flag.<br>
<br>
Indeed.<br>
<br>
<br>
On Tue, 30 Mar 2010, Dmitry Titov wrote:<br>
&gt;<br>
&gt; But if we say close() lets script run until completion (but prevents<br>
&gt; further messages/events from dispatching), then perhaps we don&#39;t need it<br>
&gt; at all - there is nothing then that script in the worker can not do to<br>
&gt; the same effect (unregister onmessage, clear timers etc).<br>
<br>
It can be a lot harder to actually find all the various things that are<br>
keeping a worker alive than just to call close().<br>
<br>
<br>
&gt; That means letting worker to call close() on itself only makes<br>
&gt; additional sense if it is specified as immediate termination. It could<br>
&gt; be useful and it can be specified in deterministic manner.<br>
<br>
I agree that immediate termination might also be useful, but if that&#39;s<br>
what you want, just don&#39;t do anything after calling close(). :-)<br>
<br>
<br>
On Thu, 1 Apr 2010, Jonas Sicking wrote:<br>
&gt;<br>
&gt; The one thing that we do and that is somewhat iffy is the close event.<br>
<br>
The close event is no longer in the spec, so at this point it&#39;s a Firefox<br>
proprietary feature. :-) We removed it to prevent exposing GC behaviour,<br>
because otherwise if pages start depending on one particular behaviour,<br>
we&#39;ll have accidentally forced the GC rules into the platform, which<br>
seems like an incredibly bad idea.<br>
<br>
<br>
&gt; [...] it exposes GC behavior. This is very unfortunate indeed and<br>
&gt; because of it I feel that our implementation is somewhat experimental.<br>
<br>
I would recommend dropping the &#39;close&#39; event for this reason.<br>
<font color="#888888"><br>
--<br>
Ian Hickson               U+1047E                )\._.,--....,&#39;``.    fL<br>
<a href="http://ln.hixie.ch/" target="_blank">http://ln.hixie.ch/</a>       U+263A                /,   _.. \   _\  ;`._ ,.<br>
Things that are impossible just take longer.   `._.-(,_..&#39;--(,_..&#39;`-.;.&#39;<br>
</font></blockquote></div><br></div>