W3C home > Mailing lists > Public > public-script-coord@w3.org > April to June 2013

Re: Future feedback

From: Jorge <jorge@jorgechamorro.com>
Date: Tue, 14 May 2013 13:46:35 +0200
Message-Id: <AC00F454-98D8-4754-A50C-01D20D48887F@jorgechamorro.com>
To: EcmaScript list <es-discuss@mozilla.org>, public-script-coord <public-script-coord@w3.org>
On 13/05/2013, at 05:37, Jonas Sicking wrote:
> On Sun, May 12, 2013 at 7:31 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:
>>> Moreover the page can be reflowed between tasks.
>> _ANY_ async solution will have this property.  What does it even mean to be
>> async if you don't allow reflows in the meantime?
> 
> Work that is performed at end-of-microtask is sort of between fully
> asynchronous and normal synchronous. Since it runs as part of the same
> task it means that reflows can't happen before the end-of-microtask
> work happens.
> 
> This means that you get some advantages of asynchronous code, such as
> not having to worry about being in an inconsistent state due to code
> higher up on the call stack being half-run. And likewise you don't
> have to worry about not messing up code higher up on the callstack
> which didn't expect to have things change under it.
> 
> But it also means that you are missing out of some of the advantages
> of asynchronous code, such as you still have to worry about hogging
> the event loop for too long and thus not processing pending UI events
> from the user.

The event loops used to look ~ like this (node's nextTick used to be === setImmediate):

while ( RUN ) {
 despatchSetImmediate();
 despatchIOandGUIandTimerEvents();
 if (!setImmediateQueue.length && !pendingEventsSignal) sleep();
}

IIUC now node's (new) event loop looks ~ like this instead (now that nextTick !== setImmediate):

while ( RUN ) {
 despatchSetImmediate();
 despatchNextTickQueue();
 despatchIOandGUIandTimerEvents();
 if (!setImmediateQueue.length && !nextTickQueue.length && !pendingEventsSignal) sleep();
}

despatchNextTickQueue() unlike despatchSetImmediate() walks its queue entirely (simplified pseudo code):

function despatchSetImmediate () {
 var queue= setImmediateQueue;
 setImmediateQueue= [];
 for (var i=0 ; i< queue.length ; i++) queue[i]();
}

function despatchNextTickQueue () {
 for (var i=0 ; i< nextTickQueue.length ; i++) nextTickQueue[i]();
 nextTickQueue.length= 0;
}

If a nextTick()ed function adds further nextTick()ed functions, those newly added functions will run in the *current* tick as well, unlike setImmediate()ed functions, which seems to be the whole point of this modified, new event loop.

Bus this also means that if nextTicked functions call nextTick() recursively the event loop blocks!

To solve that they've added a counter into despatchNextTickQueue() so that it won't ever walk in a single tick more than n elements of the nextTickQueue.

Now that means that nextTick()ed functions may sometimes behave as if setImmediate()d: you never know for sure.

To have a new event loop model that may block is a bad thing IMO, and the "let's add a counter" solution isn't a good solution.

Before the mod always knew what was going to happen, now you don't.
-- 
( Jorge )();
Received on Tuesday, 14 May 2013 11:47:16 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:37:49 UTC