BackburnerJS / backburner.js

A rewrite of the Ember.js run loop as a generic microlibrary
MIT License
392 stars 80 forks source link

Batched Reads/Writes Scheduler #345

Open lynchbomb opened 6 years ago

lynchbomb commented 6 years ago

Kicking off the idea/convo of including an API within Backburner for optimally batching work within a rAF scheduler for reads/writes. Addons obviously exist to leverage this, however it's so fundamental and a pattern we should be promoting "out-of-box" with an explicit API for doing both. Thoughts @krisselden @rwjblue @stefanpenner

  _reads: [],
  _writes: [],
  _running: false,
  scheduleRead(callback) {
    this._reads.unshift(callback);
    this._run();
  },
  scheduleWrite(callback) {
    this._writes.unshift(callback);
    this._run();
  },
  _run() {
    if (!this._running) {
      this._running = true;
      rAF(() => {
        join(() => {
         for (let i = 0, rlen = this._reads.length; i < rlen; i++) {
            this._reads.pop()();
          }
          for (let i = 0, wlen = this._writes.length; i < wlen; i++) {
            this._writes.pop()();
          }
          this._running = false;
          if (this._writes.length > 0 || this._reads.length > 0) {
            this._run();
          }
        });
      });
    }
  }
lynchbomb commented 6 years ago

From speaking with @tomdale and @rwjblue:

  1. read/write batching is something developers should fall into success with
  2. it should be baked into ember somewhere ie backburner or new micro-lib etc.
  3. we should implement a "Default" read mode
  4. write mode should be automated via component "settings" > re-render. writes then are just "run through the template and do the things"
  5. (3 + 4 above) are "behind the curtain" and automated. The idea that we should also have an explicit API of scheduleRead/Write is TBD. since we obv. don't want to add unnecessary complexity.
tomdale commented 6 years ago

I want to make sure that the primitives we're building are in terms of the abstractions of the web platform. Specifically, I think we need to carefully define how Ember's scheduling semantics interact with native platform scheduling, and possibly provide APIs that let you express scheduling in terms of both. For example, I may want to schedule a task after Glimmer has inserted elements into the DOM, but before the next frame is painted. Or I may want to schedule a task right before the browser paints, without worrying about Glimmer.

Can we get a document going enumerating all of the known use cases for when people use Backburner or otherwise schedule async tasks? I think this will help us define the imperative API, and also think about more declarative APIs we could use that give us more freedom to tweak in the future without breaking things.

Off the top of my head, this includes things like: