Skip to content
This repository has been archived by the owner on Feb 13, 2021. It is now read-only.

Waiting transaction w/ additional requests? #9

Open
inexorabletash opened this issue Jun 22, 2016 · 2 comments
Open

Waiting transaction w/ additional requests? #9

inexorabletash opened this issue Jun 22, 2016 · 2 comments

Comments

@inexorabletash
Copy link
Owner

inexorabletash commented Jun 22, 2016

Need to specify the behavior for:

  • A transaction that's in the "waiting" state
  • All of the promises in the transaction's extend lifetime promises fulfill
  • There are still outstanding requests

And also:

  • When those outstanding requests complete, new requests are made

The plausible behaviors I can think of are:

  1. Once all of the promises in the transaction's extend lifetime promises fulfill, the state transitions back to "inactive" (or "active" if we happen to be in an IDB event dispatch!), and the previous lifetime rules resume. It can be kicked back to "waiting" by further waitUntil() calls.
  2. We do transition to "committing"; any responses that come back after this point fire the usual events/resolutions, but new requests throw "InvalidStateError".

The former feels more natural to me, but the second makes sense if you consider using waitUntil() to build explicitly committing transactions:

IDBTransaction.prototype.becomeExplicit = function() {
  this.waitUntil(new Promise(resolve => { this._waiting = resolve; }));
};
IDBTransaction.prototype.commitNow = function() { this._waiting(); };

(But I still lean towards the former)

@inexorabletash
Copy link
Owner Author

Another data point in favor of behavior 1:

async function doStuff(db, url) {
  const tx = db.transaction('store', 'readwrite');
  const store = tx.objectStore('store');

  let record = await store.get(url);
  if (!record) {
    const p = fetch(url); // Pretend this yields a cloneable thing
    tx.waitUntil(p);
    const r = await p;

    // NOTE: if waitUntil(x) returns x, then above can be just:
    // const r = await tx.waitUntil(fetch(url));

    // NOTE: extend lifetime promises have fulfilled, but don't want to commit yet!
    store.put(r, url);
  }
  return record;
}

If you don't transition back to "active" then you must write the waitUntil() so that it encompasses the entire promise chain. If you do transition back to "active" then it is possible to just waitUntil() a non-IDB operation to "bring it into the fold".

@inexorabletash
Copy link
Owner Author

Note that the or "active" if we happen to be in an IDB event dispatch clause needs handling even in the case where there are no more outstanding requests. An important case to get right: the transaction is waiting on one of its own requests. The timing of the dispatch vs. resolution is also critical there - don't want to try and commit too early, nor forget to commit.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant