Re: Sync API for workers

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:40:32 UTC