I see, thanks for the details!<div><br></div><div>This makes sense - you let the worker run unrestricted (ports still send messages, sync API work) until it exits JS code. It is one of two possibilities I though of as well (run unrestricted while in JS or immediate termination).<div>
<br></div><div>BTW, the current Worker spec and WebKit do not have &#39;onclose&#39;. I&#39;m curious if FF plans to keep it. I&#39;ve tried to find relevant discussion on exact reasons it was removed but it hides from me...</div>
<div><br></div><div>Dmitry<br><div><br></div><div><div class="gmail_quote">On Wed, Mar 31, 2010 at 10:03 AM, ben turner <span dir="ltr">&lt;<a href="mailto:bent.mozilla@gmail.com">bent.mozilla@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Hi,<br>
<br>
When implementing the close() function for Firefox we chose to set the<br>
closing flag and clear pending events only. As the worker script is<br>
calling close() on itself we figured that the worker should retain<br>
maximum functionality until it has finished execution (otherwise it<br>
could just not call close() and rely on some kind of postMessage() and<br>
terminate() combo). Therefore we do not enforce any timeout for the<br>
currently executing script and we continue to allow postMessage()<br>
calls and synchronous XHR to proceed. Since the closing flag is set in<br>
response to close() the worker is guaranteed to finish as soon as the<br>
currently running script finishes. We always enforce a timeout for any<br>
code that runs in response to the close event that gets fired after<br>
the current script finishes, though.<br>
<br>
If the code that calls close() never returns (like the while(1) { }<br>
example above) then the worker will never finish, as pointed out<br>
above, but that&#39;s no different than having a worker script that<br>
consists only of a while(1) { } loop and we don&#39;t think it&#39;s important<br>
to prevent. If a worker script is written in this way then a<br>
terminate() call is still a valid solution.<br>
<br>
Also, since we try to retain maximum functionality after close() we<br>
also allow errors to propagate as shown above.<br>
<br>
If anyone is curious the basic strategy we use in response to close<br>
functions (like close(), terminate(), and for UA-generated events like<br>
when the main worker object is GC&#39;d) can be found in the following<br>
table:<br>
<br>
<a href="http://mxr.mozilla.org/mozilla-central/source/dom/src/threads/nsDOMWorker.h#202" target="_blank">http://mxr.mozilla.org/mozilla-central/source/dom/src/threads/nsDOMWorker.h#202</a><br>
<font color="#888888"><br>
-Ben<br>
</font><div><div></div><div class="h5"><br>
On Tue, Mar 30, 2010 at 6:38 PM, Dmitry Titov &lt;<a href="mailto:dimich@chromium.org">dimich@chromium.org</a>&gt; wrote:<br>
&gt;<br>
&gt; On Tue, Mar 30, 2010 at 5:58 PM, Drew Wilson &lt;<a href="mailto:atwilson@google.com">atwilson@google.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; I&#39;ll note that the spec gives the UA an significant amount of latitude<br>
&gt;&gt; about its behavior after close() is called:<br>
&gt;&gt; User agents may invoke the &quot;kill a worker&quot; processing model on a worker at<br>
&gt;&gt; any time, e.g. in response to user requests, in response to CPU quota<br>
&gt;&gt; management, or when a worker stops being an active needed worker if the<br>
&gt;&gt; worker continues executing even after its closing flag was set to true.<br>
&gt;&gt; Essentially, UAs can kill a worker at any time, and since the &quot;kill a<br>
&gt;&gt; worker&quot; algorithm allows UAs to abort the script after a user-agent-defined<br>
&gt;&gt; amount of time (including zero), it seems like almost any behavior<br>
&gt;&gt; post-close is compliant. This seems like a guaranteed source of<br>
&gt;&gt; cross-browser incompatibilities.<br>
&gt;<br>
&gt; Yes, and this, after many hours of troubles, may eventually crystallize into<br>
&gt; &quot;don&#39;t have any code after close() in your worker code&quot; rule-of-thumb for<br>
&gt; web developers. Which is basically a bad thing...<br>
&gt; This is why it could be better to specify explicitly that either execution<br>
&gt; is immediately terminated or it runs until JS exits with full functionality<br>
&gt; of the worker, not in a special almost-closed mode. Having a timeout<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; I&#39;ve always operated under the impression that the intent of the spec is<br>
&gt;&gt; to allow pending worker operations to complete, but still give UAs the<br>
&gt;&gt; ability to abort scripts that don&#39;t exit in a timely manner (so close()<br>
&gt;&gt; should not immediately abort the script), but I don&#39;t see anything in the<br>
&gt;&gt; spec regarding this.<br>
&gt;&gt; For #2 below, I believe that exceptions in worker context should *always*<br>
&gt;&gt; be reported, regardless of closing state. Section 4.6 (Runtime script<br>
&gt;&gt; errors) makes no mention of tying this behavior to the closing flag.<br>
&gt;<br>
&gt; This applies as long as the browser still executes the code after close().<br>
&gt; In WebKit V8 case, we terminate execution almost instantly, so we don&#39;t even<br>
&gt; run the code that causes an error :-) If we are not to terminate execution<br>
&gt; instantly, then it&#39;d be nice to say the script runs until it ends (or parent<br>
&gt; document closes, which actually terminates the script forcefully), and not<br>
&gt; have a requirement to stop the queue or disconnect ports, as to not create a<br>
&gt; whole new &#39;mode of worker execution&#39; which needs to have a spec on its own<br>
&gt; since all other features will need to be mentions (like sync APIs).<br>
&gt; It&#39;s not clear why a fixed timeout would be useful. It would create some<br>
&gt; randomness in what a worker can still do after calling close(). I think web<br>
&gt; developers would then rather do those things before calling close(), to<br>
&gt; avoid random results.<br>
&gt; But if we say close() lets script run until completion (but prevents further<br>
&gt; messages/events from dispatching), then perhaps we don&#39;t need it at all -<br>
&gt; there is nothing then that script in the worker can not do to the same<br>
&gt; effect (unregister onmessage, clear timers etc).<br>
&gt; That means letting worker to call close() on itself only makes additional<br>
&gt; sense if it is specified as immediate termination. It could be useful and it<br>
&gt; can be specified in deterministic manner.<br>
&gt; On a separate note, I agree with giving workers some time before terminating<br>
&gt; them in case the parent page closes - but this is the case when forces<br>
&gt; outside and async to the worker need to close it. I think<br>
&gt; it&#39;s different when worker&#39;s own script wants to terminate - it could do its<br>
&gt; last wishes before calling close() as well.<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; -atw<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; On Tue, Mar 30, 2010 at 4:44 PM, Dmitry Titov &lt;<a href="mailto:dimich@chromium.org">dimich@chromium.org</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hi!<br>
&gt;&gt;&gt; Trying to fix some bugs for Workers, I&#39;ve got some questions about<br>
&gt;&gt;&gt; close() method on WorkerGlobalScope.<br>
&gt;&gt;&gt; In particular, the spec seems to imply that after calling close() inside<br>
&gt;&gt;&gt; the worker, the JS does not get terminated right away, but rather continue<br>
&gt;&gt;&gt; to execute, while an internal &#39;closing&#39; flag is set and a message<br>
&gt;&gt;&gt; queue associated with the worker discards all the tasks, existing and<br>
&gt;&gt;&gt; future. Also, all ports are immediately disentangled.<br>
&gt;&gt;&gt; This seems to leave some questions without explicit answer, with<br>
&gt;&gt;&gt; differences in current implementations:<br>
&gt;&gt;&gt; 1. Does this code in a worker continues looping until the parent page<br>
&gt;&gt;&gt; unloads:<br>
&gt;&gt;&gt;  ...<br>
&gt;&gt;&gt;  close();<br>
&gt;&gt;&gt;  while(true) {}<br>
&gt;&gt;&gt; WebKit V8 terminates, WebKit JCS terminates after a timeout, FF does not<br>
&gt;&gt;&gt; terminate.<br>
&gt;&gt;&gt; 2. Do the errors propagate back to Worker object after close()?<br>
&gt;&gt;&gt; ...<br>
&gt;&gt;&gt; close();<br>
&gt;&gt;&gt; nonExistingFunction();  &lt;&lt;-- throws, if not processed locally, posts<br>
&gt;&gt;&gt; error info to the Worker object.<br>
&gt;&gt;&gt; In WebKit and FF errors propagate, although it does not seem consistent<br>
&gt;&gt;&gt; while worker closed all the ports and is in a dormant state.<br>
&gt;&gt;&gt; 3. Should synchronous operations work after close()? Asynchronous ones<br>
&gt;&gt;&gt; perhaps should not, because of the event loop queue which is stopped...<br>
&gt;&gt;&gt; ...<br>
&gt;&gt;&gt; close();<br>
&gt;&gt;&gt; xhr.open(&quot;GET&quot;, &quot;<a href="http://foo.com" target="_blank">foo.com</a>&quot;, false);<br>
&gt;&gt;&gt; xhr.send();<br>
&gt;&gt;&gt; WebKit: does not work (mostly), FF - does work.<br>
&gt;&gt;&gt; Perhaps it would be simpler to either say nothing is<br>
&gt;&gt;&gt; executed/posted/fired after close() (immediate termination), or to enable<br>
&gt;&gt;&gt; worker run unimpeded (with ports open, etc) until it naturally yields from<br>
&gt;&gt;&gt; JS.<br>
&gt;&gt;&gt; Any opinions?<br>
&gt;&gt;&gt; Thanks,<br>
&gt;&gt;&gt; Dmitry<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br></div></div></div>