W3C home > Mailing lists > Public > public-webapps@w3.org > July to September 2012

Re: Sync API for workers

From: Olli Pettay <Olli.Pettay@helsinki.fi>
Date: Thu, 06 Sep 2012 09:56:34 +0300
Message-ID: <50484922.8000808@helsinki.fi>
To: Jonas Sicking <jonas@sicking.cc>
CC: Glenn Maynard <glenn@zewt.org>, Andrea Marchesini <amarchesini@mozilla.com>, David Bruant <bruant.d@gmail.com>, "public-webapps@w3.org" <public-webapps@w3.org>
On 09/06/2012 09:49 AM, Jonas Sicking wrote:
> On Wed, Sep 5, 2012 at 11:30 PM, Olli Pettay <Olli.Pettay@helsinki.fi> wrote:
>> On 09/06/2012 09:12 AM, Jonas Sicking wrote:
>>> On Wed, Sep 5, 2012 at 11:02 PM, bugs@pettay.fi <bugs@pettay.fi> wrote:
>>>> On 09/06/2012 08:31 AM, Jonas Sicking wrote:
>>>>> On Wed, Sep 5, 2012 at 8:07 PM, Glenn Maynard <glenn@zewt.org> wrote:
>>>>>> On Wed, Sep 5, 2012 at 2:49 AM, Jonas Sicking <jonas@sicking.cc> wrote:
>>>>>>> The problem with a "Only allow blocking on children, except that
>>>>>>> window can't block on its children" is that you can never block on a
>>>>>>> computation which is implemented in the main thread. I think that cuts
>>>>>>> out some major use cases since todays browsers have many APIs which
>>>>>>> are only implemented in the main thread.
>>>>>> You can't have both--you have to choose one of 1: allow blocking
>>>>>> upwards,
>>>>>> 2:
>>>>>> allow blocking downwards, or 3: allow deadlocks.  (I believe #1 is more
>>>>>> useful than #2, but each proposal can go both ways.  I'm ignoring more
>>>>>> complex deadlock detection algorithms that can allow both #1 and #2, of
>>>>>> course, since that's a lot harder.)
>>>>> Indeed. But I believe #2 is more useful than #1. I wasn't proposing
>>>>> having both, I was proposing only doing #2.
>>>>> It's actually technically possible to allow both #1 and #2 without
>>>>> deadlock detection algorithms, but to keep things sane I'll leave that
>>>>> as out of scope for this thread.
>>>>> [snip]
>>>>>> I think that's by far the most
>>>>>> interesting category of use cases raised for this feature so far, the
>>>>>> ability to implement sync APIs from async APIs (or several async APIs).
>>>>> That is certainly an interesting use case. I think another interesting
>>>>> use case is being able to write synchronous APIs in workers whose
>>>>> implementation uses APIs that are only available on the main thread.
>>>>> That's why I'm not interested in only blocking on children, but rather
>>>>> only blocking on parents.
>>>>>>> The fact that all the examples that people have used while we have
>>>>>>> been discussing synchronous messaging have spun event loops in
>>>>>>> attempts to deal with messages that couldn't be handled by the
>>>>>>> synchronous poller makes me very much think that so will web
>>>>>>> developers.
>>>>>> getMessage doesn't spin the event loop.  "Spinning the event loop"
>>>>>> means
>>>>>> that tasks are run from task queues (such as asynchronous callbacks)
>>>>>> which
>>>>>> might not be expecting to run, and that tasks might be run recursively;
>>>>>> none
>>>>>> of that that happens here.  All this does is block until a message is
>>>>>> available on a specified port (or ports), and then returns it--it's
>>>>>> just
>>>>>> a
>>>>>> blocking call, like sync XHR or FileReaderSync.
>>>>> The example from Olli's proposal 3 does what effectively amounts to
>>>>> "spinning an event loop". It pulls out a bunch of events from the
>>>>> normal event loop and then manually dispatches them in a while loop.
>>>>> The behavior is exactly the same as spinning the event loop (except
>>>>> that non-message tasks doesn't get dispatchet).
>>>> It is just dispatching events.
>>>> The problems we (Gecko) have had with event loop spinning in main thread
>>>> relate mainly to the problems where "unexpected" events are dispatched
>>>> while
>>>> running the loop, as an example user input events or events coming from
>>>> network.
>>>> getMessage/waitForMessage does not have that problem.
>>> I'm not sure what you mean by "just dispatching events". That's
>>> exactly what event loop spinning is.
>> No. waitForMessage example I wrote down just dispatches DOM events in a
>> loop.
>> That is a synchronous operation and you know exactly which events you're
>> about to dispatch.
>> If you run the generic event loop, you also end up running
>> timers and getting input from network and user etc. and you can't
>> controls those.
> Just because they are message events doesn't mean that "you know
> exactly which events you're about to dispatch". That's basically
> equivalent to saying that it's safe to spin the event loop in Gecko as
> long as you only dispatch nsIRunnables that were dispatched from Gecko
> code, as opposed to native events from the native event loop.
> Note that messages can be sent to the worker in response to network
> and UI events on the main thread.
>>> Why are the gecko events any more "unexpected" than the message events
>>> that the example dispatches.
>> We don't want to block certain events in Gecko (like user input to chrome).
>> Blocking events in worker code is ok.
> I don't understand what you are saying here.
>>> If they at that point call into a library which
>>> starts pulling messages off of the task queue and dispatches them,
>>> they'll run into the same problems as we've had.
>> ...but then it is up to the library to handle the case properly and
>> dispatch events async.
> But if it dispatches them asynchronously, they have lost their place
> in the message queue. I.e. now they are placed after all other
> incoming message events. Such event reordering is likely to break
> application level logic.
> And like I said in my original email, you can fix that reordering by
> completely redoing all you message event handling and using a
> framework. But I'd like to find a solution that doesn't require that.
> Especially since that still wouldn't fix the fact that messages get
> reordered compared to other types of tasks on the task queue.
>> Though, dispatching events async so that other new message events don't get
>> handled before them
>> would require some new API.
> Exactly. And you'd have to make sure that they get dispatched in the
> correct order compared to the other events that you are pulling out
> using waitForMessage. I.e. simply an API which inserts them in the
> beginning of the task queue wouldn't be enough. You'd need something
> like an iterator which lets you iterate the task queue and inspect
> messages and only pull out selected ones. And allow that iterator to
> block once it sees no more incoming messages.
> But that is a whole lot messier than the other proposals that have
> been discussed. And what you would effectively have is something that
> amounts to a separate communication channel which you can pull
> messages out of while ignoring all other pending messages in other
> channels. So why not simply use an actual separate channel instead?

Because data sent from parent to child might arrive in different order than
in which it was sent, and workers couldn't know that, nor the parent.

(Also, proposal 1 has the rather major problem with multiple event listeners.)

> That is what proposal 1 and 2 effectively does. As does the proposals
> from Glenn and me.
> / Jonas
Received on Thursday, 6 September 2012 06:57:08 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:13:38 UTC