- From: Oliver Hunt <oliver@apple.com>
- Date: Sat, 01 Sep 2012 13:51:58 -0700
- To: Rick Waldron <waldron.rick@gmail.com>
- Cc: olli@pettay.fi, David Bruant <bruant.d@gmail.com>, "public-webapps@w3.org" <public-webapps@w3.org>
- Message-id: <DDD1FE32-0DCF-45B3-9B7D-6BC429DF73EF@apple.com>
My reading (from the proposed APIs) is that these are only synchronous from the Worker's PoV. If that's correct I have no real objections to such an API - the render thread simply sees a regular message. It doesn't even need a special API on the receiving side. If the Worker has ... var response = postSynchronousMessage(message) ... and the renderer has worker.onmessage =function() { ....; return "foo" } There are no UI blocking hazards (other than the usual slow event handler problem, which is already present anyway) The only real problem I can see is along the lines of: // Worker1 onmessage = function () { ...worker2.postSynchronousMessage(...)... } // Worker2 onmessage = function () { ...worker1.postSynchronousMessage(...)... } In the current implementations I imagine that this may cause difficulty, but I don't think that there is an actual technical argument against it. --Oliver On Sep 1, 2012, at 1:38 PM, Rick Waldron wrote: > > > On Saturday, September 1, 2012 at 4:28 PM, Olli Pettay wrote: > >> On 09/01/2012 11:19 PM, Rick Waldron wrote: >>> >>> David, >>> >>> Thanks for preparing this summary—I just wanted to note that I still stand behind my original, reality based arguments. >>> >>> One comment inline.. >>> >>> On Saturday, September 1, 2012 at 12:49 PM, David Bruant wrote: >>> >>>> Hi, >>>> >>>> A Sync API for workers is being implemented in Firefox [1]. >>>> I'd like to come back to the discussions mentionned in comment 4 of the bug. >>> The original post actually describes an async API—putting the word "sync" in the middle of a method or event name doesn't make it "sync". >>> >>> As the proposed API developed, it still retains the "event handler"-esque design (https://bugzilla.mozilla.org/show_bug.cgi?id=783190#c12). All of the >>> terminology being used is "async": >>> - event >>> - callback >>> - "onfoo" >>> >>> Even Olli's proposal example is async. https://bugzilla.mozilla.org/show_bug.cgi?id=783190#c9 (setTimeout) >>> >>> If the argument is "callback hell", save it—because if that's the problem with your program, then your doing it wrong (see: node.js ecosystem). >>> >>> >>> If this API introduces any renderer process blocking, the result will be catastrophic in the hands of inexperienced web developers. >> >> >> I haven't seen any proposal which would block rendering/main/dom thread > So far, they all look async. Just calling them "sync" doesn't make them "sync". A sync worker API: > > // really sync behaviour means blocking until this returns: > var result = rendererBlockingAPI( data ); > > Unless you specifically design that to stop everything and wait for a response (renderer blocking), JavaScript will "run to completion". > > Rick > > >> >> >> We've been thinking the following approaches: >> >> Proposal 1 >> Parent Thread: >> var w = new Worker('foo.js'); >> w.onsyncmessage = function(event) { >> event.reply('bar'); >> } >> Worker: >> var r = postSyncMessage('foobar', null, 1000 /* timeout */); >> if (r == 'bar') .. >> PRO: >> - It's already implemented :) >> CON: >> - Multiple event listeners - Multiple reply() calls. How to deal with it? >> - Multiple event listeners - is this your message? >> - Wrong order of the messages in worker if parent sends async message just before receiving sync message >> - The message must be read in order to reply >> >> >> Proposal 1.1 >> Parent Thread: >> var w = new Worker('foo.js'); >> w.onsyncmessage = function(event) { >> var r = new Reply(event); >> r.reply("bar"); // Can be called after event dispatch. >> } >> Worker: >> var replies = postSyncMessage('foobar', null, 1000 /* timeout */); >> for (var r in replies) { >> handleEachReply(r); >> } >> PRO: >> - Can handle multiple replies. >> - No awkward limitations on main thread because of reply handling >> CON: >> - A bit ugly. >> - Reply on the worker thread becomes an array - unintuitive >> - Wrong order of the messages in worker if parent sends async message just before receiving sync message >> - The Reply object must be created during event dispatch. >> >> >> Proposal 2 >> Parent Thread: >> var w = new Worker('foo.js'); >> w.setSyncHandler('typeFoobar', function(message) { >> return 'bar'; >> }); >> Worker: >> var r = postSyncMessage('typeFoobar', 'foobar', null, 1000 /* timeout */); >> if (r == 'bar') .. >> PRO: >> - no multple replyies are possible >> - types for sync messages >> CON: >> - Just a "single listener" >> - It's not based on event - it's something different compare with any other worker/parent communication. >> - Wrong order of the messages in worker if parent sends async message just before receiving sync message >> >> >> Proposal 3 >> Worker: >> postMessage("I want reply to this"); >> var events = []; >> while (var m = waitForMessage()) { >> if (m.data != /* the reply * /) { >> events.push(m); >> } else { >> // do something with message >> } >> } >> while (events.length()) { >> dispatchEvent(events.shift()); >> } >> PRO: >> - Flexible >> - the order of the events is changed by the developer >> - since there isn't any special sync messaging, multiple event listeners don't >> cause problems. >> CON: >> - complex for web developers(?) >> - The message must be read in order to reply >> - Means that you can't use libraries that use sync messages. Only frameworks are possible as all message handling needs to be aware of the new >> syncmessages. >> >> >> >> >> Atm, I personally prefer the proposal 3. >> >> >> -Olli >> >> >>> >>> >>> Rick >>>> >>>> A summary of points I find important and my comments, questions and concerns >>>> >>>> # Discussion 1 >>>> ## Glenn Maynard [2] Use case exposed: >>>> Ability to cancel long-running synchronous worker task >>>> "Terminating the whole worker thread is the blunt way to do it; that's >>>> no good since it requires starting a new thread for every keystroke, and >>>> there may be significant startup costs (eg. loading search data)." >>>> => It's a legitimate use case that has no good solution today other than >>>> cutting the task in smaller tasks between which a cancellation message >>>> can be interleaved. >>>> >>>> >>>> ## Tab Atkins [3] >>>> "If we were to fix this, it needs to be done at the language level, >>>> because there are language-level issues to be solved that can't be >>>> hacked around by a specialized solution." >>>> => I agree a lot with that point. This is a discussion that should be >>>> had on es-discuss since JavaScript is the underlying language. >>>> ECMAScript per se doesn't define a concurrency model and it's not even >>>> on the table for ES.next, but might be in ES.next.next (7?). See [concurr] >>>> >>>> ## Jonas Sicking [4] >>>> Ideas of providing control (read-only) over pending messages in workers. >>>> (not part of the current Sync API, but interesting nonetheless) >>>> >>>> >>>> >>>> # Discussion 2 >>>> ## Joshua Bell [5] >>>> "This can be done today using bidirectional postMessage, but of course >>>> this requires the Worker to then be coded in now common asynchronous >>>> JavaScript fashion, with either a tangled mess of callbacks or some sort >>>> of Promises/Futures library, which removes some of the benefits of >>>> introducing sync APIs to Workers in the first place." >>>> => What are these benefits? Is the cost of the Promises/Future library >>>> so high it >>>> Back to Tab's point of the previous discussion, this is a language >>>> issue, not an API issue. It ought to be solved at the language level >>>> >>>> >>>> ## Rick Waldron [6] >>>> "This is counter to the whole premise of Workers, which should be >>>> independent of their renderer process and certainly not block themselves >>>> while waiting for responses from the renderer (which inherently >>>> describes an async behaviour)." >>>> => Indeed. Having a blocked worker makes that when you need other tasks >>>> to happen in parallel, you need to spawn new workers which is a waste of >>>> resources, very much like Apache which opens a new thread for each HTTP >>>> connection while some thread are idling (I don't know if it's still the >>>> case, but it used to) >>>> >>>> >>>> ## Glenn Maynard [7] >>>> "I think this is a fundamental missing piece to worker communication. A >>>> basic reason for having Workers in the first place is so you can write >>>> linear code, instead of having to structure code to be able to return >>>> regularly (often awkward and inconvenient), but currently in order to >>>> receive messages in workers you still have to do that." >>>> => A basic reason for having workers is to move computation away from >>>> window to a concurrent and parallel computation unit so that the UI is >>>> not blocked by computation. End of story. Nothing to do with writing >>>> linear code. If JavaScript as it is doesn't allow people to write code >>>> as they wish, once again, it's a language issue. Either ask a change in >>>> the language or create a language that looks the way you want and >>>> compiles down to JavaScript. >>>> >>>> >>>> >>>> I wish to add that adding a sync API (even if the sync aspect is >>>> asymetrical as proposed in [1]) breaks the event-loop run-to-completion >>>> model of in-browser-JavaScript which is intended to be formalized at >>>> [concurr]. This model is what prevents web pages from ever freezing from >>>> a deadlock. The proposed API preserves this, but create the threat of >>>> deadlocks for workers. >>>> >>>> Besides programmer convenience, few arguments have been advanced to >>>> justify the breakage of the current concurrency model (I don't even >>>> think the breakage has been mentionned at all!). And as said several >>>> times, programmer convenience are more of a language issue than an API >>>> issue for the specific things we're talking about. >>>> Also, I don't think I have seen mentionned use cases of things that are >>>> not possible without a Sync API. Everything presented is already >>>> possible (sometimes at arguably high costs like Glenn Maynard's use case >>>> in discussion [1]). >>>> >>>> David >>>> >>>> [1] https://bugzilla.mozilla.org/show_bug.cgi?id=783190 >>>> [2] http://lists.w3.org/Archives/Public/public-webapps/2010OctDec/1075.html >>>> [3] http://lists.w3.org/Archives/Public/public-webapps/2010OctDec/1082.html >>>> [4] http://lists.w3.org/Archives/Public/public-webapps/2010OctDec/1086.html >>>> [5] http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0965.html >>>> [6] http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0966.html >>>> [7] http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0967.html >>>> [concurr] http://wiki.ecmascript.org/doku.php?id=strawman:concurrency >
Received on Saturday, 1 September 2012 20:52:29 UTC