Benjamin Smedberg wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 9/8/09 3:00 AM, Aaron Boodman wrote:
On Fri, Sep 4, 2009 at 12:02 AM, Chris Jones<cjo...@mozilla.com> wrote:
I propose adding the functions

 window.localStorage.beginTransaction()
 window.localStorage.commitTransaction()
or
 window.beginTransaction()
 window.commitTransaction()
I think this is a good idea! I would modify it to follow the pattern
set by the current SQLDatabase proposal, to have a callback, like
this:

window.localStorage.transaction(function() {
  // use local storage here
});

To be specific, the .transaction function would enqueue an operation to
perform at a later time when a mutex was held. The current caller would
continue to run to completion. There would never be simultaneous
transactions which could potentially conflict with eachother and require
merging or rollback.

It wasn't clear to me when this was proposed that it was asynchronous,
instead of a blocking call that *immediately* waited for the mutex and
blocked script execution.


To be clear, that's not what I had in mind at all. I envisioned a synchronous API that speaks in terms of fallible, atomic/consistent transactions. Mutexes are implementation details that the spec would not mention.

It's easy to make an async API out of a sync one by using setTimeout(0, ...). It's harder to go the other way.

Would the transaction function be defined so that it never runs immediately
but is always enqueued? Also, I think the function name should make it
clearer that it's an asynchronous callback:
window.localStorage.queueTransaction or somesuch?

I'm against having explicit begin/commit methods for the same reason
as I am for the SQLDatabase feature:

- It is easy to forget to commit
- The most likely paths in an application to be wrong are ones that
are rarely run
- Therefore many applications will contain uncommon paths that end up
hung (responsive, but still unable to make forward progress) and with
uncommitted data

I agree that this is true if you never implicitly commit the transaction.
But if you were to implicitly commit the transaction when a script runs to
completion, would that negate the most serious of these issues? I'm defining
"completion" as "all those places where the current spec says the storage
mutex is unlocked", which seems equivalent to "the places script can block
on network or UI activity".


It sounds like you're proposing to make the unit of run-to-completion implicitly delineate localStorage transactions? This is fine but it complicates the handling of failed transactions, IMHO.

I suspect that making incompatible changes to the existing storage API is
going to be a hard sell for some authors: could we continue to support
completely transaction-free access to storage, in addition to the race-free
queued version. This would allow authors (JS libraries) to do
runtime-detection of the form:

if (window.localStorage.transaction === undefined)
  window.localStorage.transaction = function(fn) {
    window.setTimeout(fn, 0);
  };


No one has responded directly to my original proposal of making |window.localStorage === undefined| until |window.transaction| or whatever has been accessed. Unlike your proposal and a similar one from Jeremy, mine is a "safe" (non-racy) way for spec-compliant UAs to "bend" backwards compatibility without explicitly breaking it. Web apps slow to change should theoretically be prepared for |window.localStorage === undefined| anyway, as not all UAs support localStorage. And if a UA doesn't support window.transaction, a web app that cares never needs to worry about racy localStorage because in non-compliant UAs, |window.transaction === undefined|.

Cheers,
Chris

Reply via email to