This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 21962 - [Custom]: Running lifecycle callbacks should be integrated with microtask processing
Summary: [Custom]: Running lifecycle callbacks should be integrated with microtask pro...
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: HISTORICAL - Component Model (show other bugs)
Version: unspecified
Hardware: PC Linux
: P2 normal
Target Milestone: ---
Assignee: Dimitri Glazkov
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 18720
  Show dependency treegraph
 
Reported: 2013-05-08 03:51 UTC by Dominic Cooney
Modified: 2013-05-22 22:40 UTC (History)
4 users (show)

See Also:


Attachments

Description Dominic Cooney 2013-05-08 03:51:46 UTC
This language should be revised:

"In addition, just before the user agent is to perform a microtask checkpoint, the user agent must invoke lifecycle callbacks for the unit of related similar-origin browsing contexts to which the scripts' browsing context belongs."

Consider the case where a MutationObserver callback does something that causes a lifecycle callback to be enqueued. That lifecycle callback may never be delivered.

Maybe the HTML5 microtask needs to be teased apart into conditions to run until a fixed point and the operations to run?

For safety in Blink I'm tempted to drop lifecycle callbacks enqueued in a MutationObserver on the floor.
Comment 1 Dominic Cooney 2013-05-08 06:00:46 UTC
Also note that microtask processing runs in a loop until they are all gone:

"3. If any MutationObserver object in scripting environment's list of MutationObserver objects has a non-empty record queue at this point, run these steps again (indeed, all of them)."

<http://dom.spec.whatwg.org/#mutation-observers>

Lifecycle events should do the same, I think.
Comment 2 Dominic Cooney 2013-05-08 06:10:40 UTC
Disregard Comment 1, I see that the looping aspect is there, just the language differs.
Comment 3 Olli Pettay 2013-05-08 08:52:24 UTC
(In reply to comment #0)
> Consider the case where a MutationObserver callback does something that
> causes a lifecycle callback to be enqueued. That lifecycle callback may
> never be delivered.

Well, MutationObserver callback itself forms a microtask.
Comment 4 Dominic Cooney 2013-05-08 12:33:29 UTC
(In reply to comment #3)
> (In reply to comment #0)
> Well, MutationObserver callback itself forms a microtask.

I'm going off "microtask checkpoint" as described here: <http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#perform-a-microtask-checkpoint>

I must be missing something obvious here. From my reading of the spec, implementations would:

1. Run lifecycle callbacks until they're exhausted.
2. Run MutationObservers until they're exhausted.
(Microtask checkpoint done.)

What happens to lifecycle callbacks that are scheduled during step 2? Before the next checkpoint the document may go away, etc.

It seems this should instead be:

While there are lifecycle callbacks or mutation observations:
  While there are lifecycle callbacks
    Deliver lifecycle callbacks
  While there are mutation observations
    Deliver mutation observations
Comment 5 Rafael Weinstein 2013-05-08 18:28:21 UTC
So it seems to me that Lifecyle events are similar enough to mutation observers that makes sense considering abstracting the mutation observer delivery mechanism to essentially allow Lifecycle event callbacks to act as observers.

Imagine that HTML defines an abstract EOMT processing model like:

-EOMTWorker

static Vector<EOMTWorker> activeWorkers

static activateWorker(EOMTWorker worker) {
  if (!activeWorkers.contains(worker))
    activeWorkers.append(worker);
}

static isDelivering = false;

static processEOMTCheckpoint() {
  if (isDelivering)
    return;
  isDelivering = true;

  while (!activeWorkers.empty()) {
    deliverNow = activeWorkers.copy();
    activeWorkers.clear();
    forEach worker in deliverNow {
      worker.invoke(); // may run script, which may activate other workers
                       // may also decide to do nothing if it no longer needs to
    }
  }

  isDelivering = false;
}
Comment 6 Dimitri Glazkov 2013-05-22 22:29:23 UTC
(In reply to comment #5)
> So it seems to me that Lifecyle events are similar enough to mutation
> observers that makes sense considering abstracting the mutation observer
> delivery mechanism to essentially allow Lifecycle event callbacks to act as
> observers.
> 
> Imagine that HTML defines an abstract EOMT processing model like:
> 
> -EOMTWorker
> 
> static Vector<EOMTWorker> activeWorkers
> 
> static activateWorker(EOMTWorker worker) {
>   if (!activeWorkers.contains(worker))
>     activeWorkers.append(worker);
> }
> 
> static isDelivering = false;
> 
> static processEOMTCheckpoint() {
>   if (isDelivering)
>     return;
>   isDelivering = true;
> 
>   while (!activeWorkers.empty()) {
>     deliverNow = activeWorkers.copy();
>     activeWorkers.clear();
>     forEach worker in deliverNow {
>       worker.invoke(); // may run script, which may activate other workers
>                        // may also decide to do nothing if it no longer
> needs to
>     }
>   }
> 
>   isDelivering = false;
> }

I agree. The spec already has sorting tables as a separate sequential step in microtask checkpoint, which means we could definitely end up  with pending sorts when exiting the the checkpoint:

http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#perform-a-microtask-checkpoint

Should attempt to monkey-patch this in custom elements spec? That seems a bit crazy :)
Comment 7 Dimitri Glazkov 2013-05-22 22:40:45 UTC
https://dvcs.w3.org/hg/webcomponents/rev/4963a4286660

There, FTFY.