- From: Glenn Maynard <glenn@zewt.org>
- Date: Wed, 29 Dec 2010 13:33:51 -0500
- To: Jonas Sicking <jonas@sicking.cc>
- Cc: public-webapps@w3.org
On Wed, Dec 29, 2010 at 4:56 AM, Jonas Sicking <jonas@sicking.cc> wrote: > I definitely agree that workers need more features to take advantage > of the fact that they are running on their own event loop. One of > which is the one you are asking for. > > We could add something like: > > boolean checkPendingMessages(); > > which would return true if there are pending messages. The script > running in the worker could use this information to return to the > event loop to process these messages only when needed. One downside > with this API is that there is a risk that people could write: Is there a problem with synchronously delivering the next pending message event, rather than having to return all the way out to allow it to run? Code shouldn't need to be engineered to allow returning and resuming in order to receive messages, as if we're still in a UI thread. Note that it's critical that this run only events from a specific message port, so only targetted messages are run and not unrelated ones. I've used this approach with C++ worker threads and it works very well; it allows thread work to be cancelled at specific, predetermined points, without exposing significant threadsafety issues to the thread itself, and allowing deeply nested algorithm code to handle cancellation in a consistent way: var checkForCancellation() { // run all waiting messages from this port while(cancellationPort.runPendingMessage()) ; // if a message set cancellation, stop working if(cancel) throw "Operation cancelled"; } try { checkForCancellation(); doStuff(); while(var i = 0; i < longRunningLoop; ++i) { checkForCancellation(); doMoreWork(); } } catch... > An alternative solution would be something like: > > MessageInfo getMessageIfExists(); > > which would return an object containing the message data if a message > was pending and remove the message from the queue of pending messages. > If there are no pending messages null is returned and the message > queue remains empty. This makes it significantly harder to write code > like the above. However it might make coding somewhat more awkward > since you likely will have to deal with messages arriving two ways, > through the normal event loop and through getMessageIfExists. I avoided that in my suggestion, since it seems likely to cause confusing bugs and it's hard to think of when this behavior would really be wanted. If it was, you could do something like this, I think: function getPendingMessageWithoutDelivery(port) { var onmessage = port.onmessage; try { port.onmessage = null; return port.runPendingMessage(); // returns the handled message or null if none } finally { port.onmessage = onmessage; } } -- Glenn Maynard
Received on Wednesday, 29 December 2010 18:34:24 UTC