- From: Chris Jones <cjones@mozilla.com>
- Date: Wed, 09 Sep 2009 11:59:23 -0500
Jeremy Orlow wrote: > Those who want a queue. I.e. those who want an asynchronous > callback based interface and the UA will only call one callback > at a time. Perhaps on a per-origin basis. Note that this can > never "fail", need to be rolled back, etc. > > > This sounds to me like { traditional transactions, async, > unobservable transaction failures } which is the same as your first > camp above except async only. Or are you proposing that the unit of > atomicity/consistency is not all operations performed in the > callback; i.e., that modifications done in the callback can be > partially applied? > > > It's just an implementational difference. A queue means that the event > loop can continue processing stuff while waiting for the 'lock' (which > maybe is better described as an 'update token' or something). If you > implement it as a lock (which you would for a synchronous interface) > then the event loop is blocked. > OK, agreed. What we describe reduce to the same thing --- the "trylock" implementation Rob O'Callahan and I discussed would also never block the event loop. But I better understand now what you have in mind. (I'm not sure which is better, but that's what implementation details are all about!) > > I believe Aaron is in the queue camp with me. I'm becoming more > and more convinced that Chromium should/will not implement the > storage mutex at all (even for LocalStorage) unless we can come > up with a way for event loops to not be blocked. And, as far as > I can tell, Async interfaces are the only way to accomplish this. > > > In general, agreed. I still believe that a sync API > > > The problem with a sync interface, especially if it's one that can be > held after the top level script context, is deadlock issues with > WebDatabase (and possibly others). What's there now doesn't have this > issue because you'd never have the lock when calling the database > transaction callback. > I didn't think of Web Database, although I had in mind a nonblocking implementation of localStorage (i.e., no mutex) that would prevent it from participating in deadlocks. But in general, nesting transactions, both { localStorage { Web DataBase } } and { localStorage { localStorage } }, is something the spec should explicitly disallow. There's not a clearly best way to resolve the semantic problems that arise. (Note that preventing nested transactions also eliminates deadlock concerns for mutex implementations.) > > with exposed transaction failures > > > You'll only have transaction failures in an optimistic transaction > model, right? So is that what you're suggesting? > > > (as I proposed in the OP) and the right implementation could do > quite well. But I now think that an async version of that same API > could perform even better. In addition, that API is most flexible > in terms of possible UA implementations. > > > IOW, I think that { traditional transactions, async, observable > failures } subsumes both { traditional transactions, sync, > observable failures } (OP's proposal) *and* { traditional > transactions, async, unobservable failures } (your and Aaron's > proposal). > > > IMHO there are two remaining questions: first, whether the "ideal" > localStorage transactional API should allow observable transaction > failures. I believe that it should, as this allows for the widest > variety of efficient implementations without changing ACID (best > effort) guarantees given to authors or significantly complicating > the localStorage API. > > > What failures could there be in a pesimistic/queue model? > I'm trying to think of a "universal failure," something that could arise in any implementation of any proposal. I think that universal failure is "exceeded localStorage space quota". (I believe there are others, but one is enough for this discussion.) So there are really two questions: first, what happens if you detect "quota exceeded" in the middle of a localStorage.transaction() callback? Are the modifications made *up to* the quota exceeded error applied to backing store? Or are they rolled back? This is the atomicity/consistency design decision I described: what is the unit of atomic modification (all applied or none applied). And second, can scripts be notified that the transaction failed (or was only partially applied) because of quota exceeded? AFAICT this is irrespective of sync/async/optimistic/pessimistic/queue. Any implementation has to deal with this error somehow. In the current localStorage spec, if a setItem() fails because space is exhausted, it raises QUOTA_EXCEEDED_ERR and does *not* apply any part of the change in setItem(). That is, setItem() is atomic --- it either applies or not (not partially applied). But modifications to localStorage *before* that failing setItem(), within the same storage mutex acquire/release set, *are* applied to backing store. In the Web Database spec, if executing a SQL statement in a Transaction would cause space quota to be exceeded, then *none* of the statements in the transaction are executed (i.e. none committed to backing store), and the Transaction fails with QUOTA_ERR. The unit of atomicity for Web Database is that Transaction object --- either all statements in Transaction successfully execute or none do. I'm not sure whether you're proposing that modifications within a localStorage.transaction() callback are atomic (all applied or none applied) in the face of quota exceeded. (I'm proposing that they *should* be atomic.) It sounds like you're proposing that scripts *cannot* be notified of quota exceeded. If this is true, then there are some semantic issues I'd like to discuss. But I want to make sure we're on the same page first :). (I'm proposing that scripts *should* be able to be notified of this.) > Second, what is the best way to go forward with transactional > localStorage while remaining backwards-compatible with current > implementations. One option would be to deprecate localStorage in > favor of a future, transactional window.domainStorage or somesuch. > > > If we do this, we might as well just adopt something like the > WebSimpleDatabase proposal (which I still haven't gotten around to > reading yet) which seems much more powerful in many other ways. > Certainly a matter of taste, but I like localStorage's API, I'd like to see it succeed. > In addition, for cases like "clear private data", UAs would be > allowed to silently break storage-mutex isolation for apps using the > non-transactional API. > > > I think it'd be better if they waited for the lock to be freed. Should be clear that this is for users of the deprecated, non-transactional API only. Isolation wouldn't be broken for transactional users. By the storage mutex spec, without the caveat that isolation may be sometimes broken, even non-malicious pages that don't exceed the slow script timeout might be able to (unknowingly) cooperate to indefinitely prevent a MELUA from clearing private data (assuming clear private data isn't a blocking operation in the MELUA). The UA might be able to prevent that with some fancy footwork, but I don't see the point in doing that for a deprecated API. Cheers, Chris
Received on Wednesday, 9 September 2009 09:59:23 UTC