I can try to say the same thing Drew is saying shorter: Workers queue all messages from main page until the moment the "initial script" is run. Initial script is the JS code outside of any function. If that initial script registers 'onmessage', all queued messages are delivered. If it doesn't - queued massages are dropped.<div>
<br></div><div>This means the worker better register 'onmessage' in its initial code, not from some other event handler.</div><div><br></div><div>Dmitry<br><br><div class="gmail_quote">On Tue, Aug 3, 2010 at 2:09 PM, Drew Wilson <span dir="ltr"><<a href="mailto:atwilson@chromium.org">atwilson@chromium.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><br><div class="gmail_quote"><div class="im">On Tue, Aug 3, 2010 at 1:40 PM, Rik Sagar <span dir="ltr"><<a href="mailto:org.whatwg@sagar.org" target="_blank">org.whatwg@sagar.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>I would expect in this example that the <i>Worker got loaded</i> message should be dropped on the floor.<br><br></blockquote></div><div>I would expect exactly the opposite - that message should be delivered.</div><div>
<br>
</div><div>Here's the way I look at worker messaging (and events in general) - each javascript context (or "thread" if you will) has what amounts to an event loop. When your javascript code returns from an event handler (or, in the case of worker script, returns from an event handler or returns from executing the initial block of script), you drop back in to your event loop and start dispatching events.</div>
<div><br></div><div>There are a number of things that can generate events (that can be "event sources") - for example, a timer is an event source. MessagePorts (both explicit MessagePorts and also implicit ones for Dedicated Workers) are event sources, too. When you queue up an event for a MessagePort, it becomes an active event source (meaning that when the associated javascript context re-enters its event loop, that MessagePort can cause an onmessage event to be generated). The event loop traverses the various associated event sources for the javascript context (timers, message ports, etc) and fires off an event from one of the event sources (the spec doesn't specify an ordering here, so it's up to the UA to decide how to prioritize various event sources) - when it fires off the event, any handlers associated with that event will receive the event, and if there are no handlers the typical default handling of the event occurs (gets dropped on the floor, or maybe gets bubbled up in the case of DOM events, etc).</div>
<div><br></div><div>So, in your case above, here's what happens - webapp_main creates a worker and then adds an "onmessage" handler to the worker object. Now, webapp_worker runs, sets up an onmessage handler (which, btw, will never be executed since you never send any messages to the worker in your example), then fires off a "Worker got loaded" message to webapp_main. Even if this code is executed before webapp_main has set its onmessage handler, the event will not get dropped on the floor - remember that all postMessage() does is put the event in the MessagePort's queue, then make that MessagePort an active event source. So as long as webapp_main sets an onmessage handler before it returns back to the event loop, there's no way for the event to get dropped on the floor because the event isn't even dispatched until you get back to the event loop.</div>
<div><br></div><div>Hopefully this helps clear up some of the confusion - it's important to understand that the various flavors of postMessage() are entirely asynchronous and rely on events being dispatched from the event loop.</div>
<div><div></div><div class="h5">
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks,<br>Rik.<br><font color="#888888"><br><br><br><br clear="all">Rik Sagar, San Jose, CA 95124<br>
Visit : <a href="http://sagar.org/" target="_blank">http://sagar.org/</a></font><div><div></div><div><br>
<br><br><div class="gmail_quote">On Mon, Aug 2, 2010 at 10:09 AM, Drew Wilson <span dir="ltr"><<a href="mailto:atwilson@chromium.org" target="_blank">atwilson@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<div class="gmail_quote">(sending from the correct address this time)<br><div><div><div><font face="sans-serif, 'Droid Sans Fallback'"><span style="line-height:21px;font-size:medium"><br>
</span></font><div class="gmail_quote">On Mon, Aug 2, 2010 at 7:57 AM, Jeremy Orlow <span dir="ltr"><<a href="mailto:jorlow@google.com" target="_blank">jorlow@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<br><br><div class="gmail_quote"><div><div></div><div>---------- Forwarded message ----------<br>From: <b class="gmail_sendername">Tobias Sauerwein</b> <span dir="ltr"><<a href="mailto:tobias.sauerwein@camptocamp.com" target="_blank">tobias.sauerwein@camptocamp.com</a>></span><br>
Date: Tue, Jul 27, 2010 at 8:46 AM<br>Subject: [html5] Web Workers: Race-Condition setting onmessage handler?<br>To: <a href="mailto:help@lists.whatwg.org" target="_blank">help@lists.whatwg.org</a><br><br><br>Hi!<br><br>
I am wondering what prevents a web worker from running into race-conditions when setting the onmessage handlers. I am worried about that a web worker posts a message before the main script has set up the onmessage handler, or the other way around, that the web worker posts a message before the main script has set up its onmessage handler.<br>
<br>I know that there is a message queue [1], but you can easily make up an example where a message is not enqueued:<br><br>Main Script:<br><br><blockquote style="border-left:1px solid rgb(204, 204, 204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex" class="gmail_quote">
var worker = new Worker("webworker.js");<br>worker.onmessage = function(event) {<br> console.log('onmessage ' + event.data) <br>};<br>worker.postMessage("start");<br></blockquote><br><br>
'webworker.js':<br><br><blockquote style="border-left:1px solid rgb(204, 204, 204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex" class="gmail_quote">setTimeout(<br> function() {<br> onmessage = function(event) {<br>
postMessage("message received"); <br> };<br> postMessage("done");<br> }, 1000);<br></blockquote><br><br>The output is (in Chromium 6.0.475.0 and Firefox 4.01b, Opera 10.70 also outputs "onmessage message received"):<br>
<br><blockquote style="border-left:1px solid rgb(204, 204, 204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex" class="gmail_quote">onmessage done<br></blockquote><br>So the "onmessage" handler of the web worker is never called.<br>
<br><br>Is this the behavior the specification requests, or is it a bug in Chrome/Chromium and Firefox?<br><br>Tobias<br><br><br><br>[1]: <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#port-message-queue" target="_blank">http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#port-message-queue</a><br>
<br></div></div>_______________________________________________<br>
Help mailing list<br>
<a href="mailto:Help@lists.whatwg.org" target="_blank">Help@lists.whatwg.org</a><br>
<a href="http://lists.whatwg.org/listinfo.cgi/help-whatwg.org" target="_blank">http://lists.whatwg.org/listinfo.cgi/help-whatwg.org</a><br>
<br></div><br>
</blockquote></div>This is the correct behavior. If there is no onmessage event at the time that an event arrives at the worker's event loop, it will be dropped on the floor. The reason this happens is steps 7/8 in section 4.5 of the worker spec:<div>
<br></div><div><span style="font-family:sans-serif,'Droid Sans Fallback';font-size:medium;line-height:21px"><span title="jump to a code entry-point" style="border-bottom-style:solid;border-bottom-color:rgb(153, 204, 153)">7. Jump</span> to the <span title="concept-script" style="border-bottom-style:solid;border-bottom-color:rgb(153, 204, 153)">script</span>'s <i>initial code entry-point</i>, and let that run until it either returns, fails to catch an exception, or gets prematurely aborted by the "<a href="http://www.whatwg.org/specs/web-workers/current-work/#kill-a-worker" style="color:rgb(0, 0, 204);background-color:transparent" target="_blank">kill a worker</a>" or "<a href="http://www.whatwg.org/specs/web-workers/current-work/#terminate-a-worker" style="color:rgb(0, 0, 204);background-color:transparent" target="_blank">terminate a worker</a>" algorithms defined below.<br>
8. If <var title="">worker global scope</var> is actually a <code style="font-size:inherit;font-family:monospace,'Droid Sans Fallback',sans-serif;font-variant:normal;color:rgb(255, 69, 0)"><a href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope" style="color:inherit;background-color:transparent" target="_blank">DedicatedWorkerGlobalScope</a></code> object (i.e. the worker is a dedicated worker), then enable the <span style="border-bottom-style:solid;border-bottom-color:rgb(153, 204, 153)">port message queue</span> of the worker's implicit port.</span></div>
<div><span style="font-family:sans-serif,'Droid Sans Fallback';font-size:medium;line-height:21px"><br></span></div><div><span style="font-family:sans-serif,'Droid Sans Fallback';line-height:21px">Basically, once the initial worker script returns, the worker's port is enabled and the normal message port event delivery mechanism kicks in (including dropping unhandled messages on the floor). I can't say whether Opera's behavior is correct or not based on your description - if you increase the timeout from 1 second to 10 seconds, do you still get the "onmessage message received"? If so, then that may be a bug in Opera because events delivered to workers without an onmessage handler set should be dropped.</span></div>
<div><span style="font-family:sans-serif,'Droid Sans Fallback';line-height:21px"><br></span></div><div><span style="font-family:sans-serif,'Droid Sans Fallback';font-size:medium;line-height:21px"><span style="font-size:small">-atw</span></span></div>
</div></div></div>
</div><br>
<br>_______________________________________________<br>
Help mailing list<br>
<a href="mailto:Help@lists.whatwg.org" target="_blank">Help@lists.whatwg.org</a><br>
<a href="http://lists.whatwg.org/listinfo.cgi/help-whatwg.org" target="_blank">http://lists.whatwg.org/listinfo.cgi/help-whatwg.org</a><br>
<br></blockquote></div><br>
</div></div></blockquote></div></div></div><br>
<br>_______________________________________________<br>
Help mailing list<br>
<a href="mailto:Help@lists.whatwg.org">Help@lists.whatwg.org</a><br>
<a href="http://lists.whatwg.org/listinfo.cgi/help-whatwg.org" target="_blank">http://lists.whatwg.org/listinfo.cgi/help-whatwg.org</a><br>
<br></blockquote></div><br></div>