[whatwg] RFC: Alternatives to storage mutex for cookies and localStorage
Chris Jones
cjones at mozilla.com
Tue Sep 8 13:38:33 PDT 2009
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<cjones at 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
More information about the whatwg
mailing list