question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Microtask update introduced event dropping

See original GitHub issue

Copied from the excellent writeup @ef4 did in https://github.com/emberjs/ember.js/issues/16296:


Hello fans of timing bugs, today I have a fun one for you.

The new microtask-based autorun architecture can drop scheduled events. To see it in action, you can run the following against 3.1 beta:

import Controller from '@ember/controller';
import { schedule } from '@ember/runloop';

export default Controller.extend({
  actions: {
    testIt() {
      // Here I am deliberately escaping the run loop to use autoruns instead.
      Promise.resolve().then(() => {
        // This schedules an autorun
        schedule('render', () => {
          console.log(1);
          // Here we schedule a microtask. It will be ahead of the runloop's own next flush.
          Promise.resolve().then(() => {
            console.log(2);
            return Promise.resolve().then(() => {
              // This runs fine
              console.log(3);
              // But this scheduled event never fires.
              schedule('actions', () => console.log('THIS NEVER RUNS!!!!') )
            });
          })
          // when we return out of here, the runloop goes back to the 
          // first queue to start flushing again. But our promise stack is
          // interleaving with the runloop's one-microtask-per-queue.
        });
      });
    }
  }
});

If you fire the testIt event, the console logs

1
2
3

The number of layers of promises required to experience the bug depends on which queue you’re trying to schedule. The runloop spends one microtask per queue, so our stack of promise resolutions is interleaved with each queue’s flush. In the above example, we schedule on the actions queue immediately after that queue has just flushed, and the runloop never notices.

You can make it drop events on any other queue just by varying the number of promises you resolve in between the time you first trigger an autorun and the time you schedule your doomed event.

I published a working example of the bug here: https://github.com/ef4/bug-repro/tree/bad-timing

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:5

github_iconTop GitHub Comments

6reactions
rwjbluecommented, May 31, 2018

This was fixed by https://github.com/BackburnerJS/backburner.js/pull/336, and the version of backburner using microtasks is included by Ember since 3.2.0-beta.1.

0reactions
Dhaulagiricommented, Mar 22, 2018

@rwjblue excellent, thanks for confirming. I’ll open an issue against Ember then, although I’m at a bit of a loss as to how best to get a useful reproduction other than the tests used to work and now they don’t 🌵

Read more comments on GitHub >

github_iconTop Results From Across the Web

Difference between microtask and macrotask within an event ...
Separation of macro and microtask enables the event loop to prioritize types of tasks; for example, giving priority to performance-sensitive tasks. In a...
Read more >
Readers' Questions: "Why does Ember still use RSVP?"
Hello once again to Readers' Questions, presented by the Ember.js Times. Today I'm answering this question: Why does Ember ship with RSVP ...
Read more >
Using microtasks in JavaScript with queueMicrotask()
First, each time a task exits, the event loop checks to see if the task is returning control to other JavaScript code. If...
Read more >
Introduction to React v18 automatic batch updates and ...
React uses microtasks under the hood to batch state updates which is why React has dropped support for internet explorer (ref) which does...
Read more >
Spin the event loop - HTML Spec - WhatWG
Living Standard — Last Updated 26 December 2022 ... 8.1.1 Introduction ... Queue a microtask on the surrounding agent's event loop to perform...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found