On Wed, Sep 9, 2009 at 4:39 AM, Chris Jones <span dir="ltr"><<a href="mailto:cjones@mozilla.com">cjones@mozilla.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Aaron Boodman wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
On Tue, Sep 8, 2009 at 11:23 AM, Chris Jones<<a href="mailto:cjones@mozilla.com" target="_blank">cjones@mozilla.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
In general, I agree with Rob about this proposal.  What problem with storage<br>
mutex as spec'd today does your proposal solve?<br>
</blockquote>
<br>
The spec requires a single storage mutex for the entire UA. Therefore<br>
in a MELUA a web page can become unresponsive while waiting for some<br>
other page to give up the lock. This is not good and something we have<br>
tried to avoid everywhere else in the spec.<br>
<br>
Attempts to address this by doing per-origin locks wind up with<br>
deadlocks being possible.<br>
<br>
</div><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Aaron Boodman wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Tue, Sep 8, 2009 at 1:41 AM, Robert O'Callahan<<a href="mailto:robert@ocallahan.org" target="_blank">robert@ocallahan.org</a>><br>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
What is the intended semantics here? Chris' explicit commitTransaction<br>
would<br>
throw an exception if the transaction was aborted due to data<br>
inconsistency,<br>
leaving it up to the script to retry --- and making it clear to script<br>
authors that non-storage side effects during the transaction are not<br>
undone.<br>
How would you handle transaction aborts?<br>
</blockquote>
Calls to transaction() are queued and executed serially per-origin<br>
with exclusive access. There is no such thing as a transaction abort<br>
because there cannot be consistency problems because of the serialized<br>
access.<br>
<br>
</blockquote>
No, transactions can still fail.  They can fail in ways immediately hidden<br>
from the script that requested them if the UA has to interrupt the<br>
conceptually executing transaction in the ways enumerated in a separate<br>
branch of this thread.  Later script executions can observe inconsistent<br>
state unless more is specified by your proposal.<br>
<br>
Transactions can also fail visibly if write-to-disk fails (probably also in<br>
other ways I haven't considered).  It's not clear what should happen wrt to<br>
your proposal in this case.<br>
</blockquote>
<br></div><div class="im">
If so, I agree with roc's responses to them that they could probably<br>
be handled without surfacing errors to the developer.<br>
<br>
OTOH, I'm not really against adding the concept of fallibility here.<br>
<br>
</div><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
In fact, I believe that the "Synchronous database API" describes the same<br>
transaction semantics as I proposed in the OP.  That spec adds implicit<br>
begin/commitTransaction and read-only transactions, but otherwise the<br>
semantics are the same.<br>
<br>
So I'd like to amend my original proposal to be<br>
<br>
 Use Synchronous Web Database API transaction semantics.  Except do not<br>
offer readTransaction: a transaction is implicitly a read-only transaction<br>
if only getItem() is called on localStorage from within<br>
localStorage.transaction().<br>
</blockquote>
<br>
Agree. That is what I was trying to propose, too. I'm not sure where<br>
we disagree :). Is it just that my proposal has no concept of errors?<br>
I'm not against adding them, mainly I was trying to keep my proposal<br>
simple for purposes of discussion.<br>
<br>
</div></blockquote>
<br>
Ay, there's the rub: I think the disagreement is between "mutex" vs. "transaction" semantics.  So far, I think perhaps "mutex" has been used as shorthand for "transaction."  But they aren't the same.<br>


<br>
I think we all agree that a script may fail to modify localStorage in some situations (irrespective of global mutex vs. per-domain mutex). One camp, wanting "mutex" semantics, would prefer to pretend that the failures never happen and let scripts clean up the mess (partially-applied changes) if they do occur.  This is semantically broken, IMHO.<br>


<br>
The second camp, wanting "transaction" semantics, explicitly acknowledge to web authors that localStorage is fallible, guarantee that modifications to localStorage are atomic, and notify scripts when modifications can't be made atomically.  This is the same approach taken by Web Database.  IMHO, this is much better semantically because (i) it gives web apps stronger guarantees; and (ii) it makes the discussion about global mutex/per-domain mutex/non-blocking an implementation issue rather semantic issue, as it should be.<br>


<br>
Can those in the first camp explain why "mutex" semantics is better than "transaction" semantics?  And why it's desirable to have one DB spec specify "transaction" semantics (Web Database) and a second specify "mutex" semantics (localStorage)?</blockquote>

<div><br></div><div>The way I understand it, there's 3 camps...and I think they've been abusing both the word transaction and mutex.  We should probably all start being more precise with our wording in this respect.  :-)</div>

<div><br></div><div><br></div><div>Those who want pessimistic transactions.  I.e. using locking so that you never need to do a rollback (because it can never "fail").  This would be compatible with either a sync or an async interface.</div>

<div><br></div><div>Those who optimistic transactions.  I.e. rollback may happen.  Either we need to restrict what can be done during a localStorage transaction or we need to have an exception that tells the script to undo itself.  This was the original proposal, AFAICT.  It would work with both a sync or an async interface.</div>

<div><br></div><div>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.</div>

<div><br></div><div><br></div><div>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.</div>

</div>