Re: Sync API for workers

On Sat, Sep 1, 2012 at 4:51 PM, Oliver Hunt <oliver@apple.com> wrote:

> 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.
>
>
Perhaps I misread or misinterpreted the goals of the proposal and while I
appreciate the clarification here, I'm still left wondering: what is the
benefit of a synchronous in-worker-only messaging API if the alleged pain
point is the desire to write "linear code".

That aside, I agree with Oliver, if no renderer process blocking can occur
and no existing APIs are broken, then there is no harm (aside from
polluting the global object with more verbosely named APIs, but that's just
a nit) .

Rick



> --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 21:09:02 UTC