<div class="gmail_quote">On Thu, Sep 24, 2009 at 11:57 PM, Jonas Sicking <span dir="ltr">&lt;jonas@sicking.cc&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5">On Thu, Sep 24, 2009 at 9:04 PM, Darin Fisher &lt;<a href="mailto:darin@chromium.org">darin@chromium.org</a>&gt; wrote:<br>
&gt; On Thu, Sep 24, 2009 at 4:43 PM, Jonas Sicking &lt;jonas@sicking.cc&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; On Thu, Sep 24, 2009 at 10:52 AM, Darin Fisher &lt;<a href="mailto:darin@chromium.org">darin@chromium.org</a>&gt; wrote:<br>
&gt;&gt; &gt; On Thu, Sep 24, 2009 at 10:40 AM, Jonas Sicking &lt;jonas@sicking.cc&gt;<br>
&gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; On Thu, Sep 24, 2009 at 1:17 AM, Darin Fisher &lt;<a href="mailto:darin@chromium.org">darin@chromium.org</a>&gt;<br>
&gt;&gt; &gt;&gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt; On Thu, Sep 24, 2009 at 12:20 AM, Jonas Sicking &lt;jonas@sicking.cc&gt;<br>
&gt;&gt; &gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; On Wed, Sep 23, 2009 at 10:19 PM, Darin Fisher &lt;<a href="mailto:darin@chromium.org">darin@chromium.org</a>&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; wrote:</div></div></blockquote><div><br></div><div>... snip ...</div><div>  </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div><div class="h5">

&gt;&gt; &gt;&gt; &gt;&gt; &gt; multi-core is the future.  what&#39;s the opposite of fine-grained<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; locking?<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;  it&#39;s not good ;-)<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; the implicit locking mechanism as spec&#39;d is super lame.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;  implicitly<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; unlocking under<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; mysterious-to-the-developer circumstances!  how can that be a good<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; thing?<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; storage.setItem(&quot;y&quot;,<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; function_involving_implicit_unlocking(storage.getItem(&quot;x&quot;)));<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; I totally agree on all points. The current API has big<br>
&gt;&gt; &gt;&gt; &gt;&gt; imperfections.<br>
&gt;&gt; &gt;&gt; &gt;&gt; However I haven&#39;t seen any workable counter proposals so far, and I<br>
&gt;&gt; &gt;&gt; &gt;&gt; honestly don&#39;t believe there are any as long as our goals are:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; * Don&#39;t break existing users of the current implementations.<br>
&gt;&gt; &gt;&gt; &gt;&gt; * Don&#39;t expose race conditions to the web.<br>
&gt;&gt; &gt;&gt; &gt;&gt; * Don&#39;t rely on authors getting explicit locking mechanisms right.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; The current API exposes race conditions to the web.  The implicit<br>
&gt;&gt; &gt;&gt; &gt; dropping of the storage lock is that.  In Chrome, we&#39;ll have to drop<br>
&gt;&gt; &gt;&gt; &gt; an existing lock whenever a new lock is acquired.  That can happen<br>
&gt;&gt; &gt;&gt; &gt; due to a variety of really odd cases (usually related to nested loops<br>
&gt;&gt; &gt;&gt; &gt; or nested JS execution), which will be difficult for developers to<br>
&gt;&gt; &gt;&gt; &gt; predict, especially if they are relying on third-party JS libraries.<br>
&gt;&gt; &gt;&gt; &gt; This issue seems to be discounted for reasons I do not understand.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; I don&#39;t believe we&#39;ve heard about this before, so that would be the<br>
&gt;&gt; &gt;&gt; reason it hasn&#39;t been taken into account.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; So you&#39;re saying that chrome would be unable implement the current<br>
&gt;&gt; &gt;&gt; storage mutex as specified in spec? I.e. one that is only released at<br>
&gt;&gt; &gt;&gt; the explicit points that the spec defines? That seems like a huge<br>
&gt;&gt; &gt;&gt; problem.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; No, no... my point is that to the application developer, those<br>
&gt;&gt; &gt; &quot;explicit&quot;<br>
&gt;&gt; &gt; points will appear quite implicit and mysterious.  This is why I called<br>
&gt;&gt; &gt; out third-party JS libraries.  One day, a function that you are using<br>
&gt;&gt; &gt; might transition to scripting a plugin, which might cause a nested<br>
&gt;&gt; &gt; loop, which could then force the lock to be released.  As a programmer,<br>
&gt;&gt; &gt; the unlocking is not explicit or predictable.<br>
&gt;&gt;<br>
&gt;&gt; Ah, indeed, this is a problem. However the unfortunate fact remains<br>
&gt;&gt; that so far no other workable solution has been proposed.<br>
&gt;<br>
&gt; OK, so we agree that the current solution doesn&#39;t meet the goals you<br>
&gt; stated above :-(<br>
<br>
</div></div>Well, it addresses them as long as users are aware of the risk, and<br>
properly document weather their various library functions will release<br>
the lock or not. However I agree that it&#39;s unlikely that they will do<br>
so correctly.</blockquote><div><br></div><div><div>I thought the point of not having lock APIs was that users shouldn&#39;t have</div><div>to understand locks ;-)  The issue I&#39;ve raised here is super subtle.  We</div>
<div>have not succeeded in avoiding subtlety!</div></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
&gt;&gt; &gt; Moreover, there are other examples which have been discussed on the<br>
&gt;&gt; &gt; list.  There are some DOM operations that can result in a frame<br>
&gt;&gt; &gt; receiving<br>
&gt;&gt; &gt; a DOM event synchronously.  That can result in a nesting of storage<br>
&gt;&gt; &gt; locks,<br>
&gt;&gt; &gt; which can force us to have to implicitly unlock the outermost lock to<br>
&gt;&gt; &gt; avoid<br>
&gt;&gt; &gt; deadlocks.  Again, the programmer will have very poor visibility into<br>
&gt;&gt; &gt; when<br>
&gt;&gt; &gt; these things can happen.<br>
&gt;&gt;<br>
&gt;&gt; So far I don&#39;t think it has been shown that these events need to be<br>
&gt;&gt; synchronous. They all appear to be asynchronous in gecko, and in the<br>
&gt;&gt; case of different-origin frames, I&#39;m not even sure there&#39;s a way for<br>
&gt;&gt; pages to detect if the event was fired asynchronously or not.<br>
&gt;<br>
&gt; IE and WebKit dispatch some of them synchronously.  It&#39;s hard to say which<br>
&gt; is correct or if it causes any web compat isues.  I&#39;m also not sure that we<br>
&gt; have covered all of the cases.<br>
<br>
</div>It still seems to me that it&#39;s extremely unlikely that pages depend on<br>
cross origin events to fire synchronously. I can&#39;t even think of a way<br>
to test if a browser dispatches these events synchronously or not. Can<br>
you?</blockquote><div><br></div><div><div><br></div><div>i agree that it seems uncommon.  maybe there could be some odd app that</div><div>does something after resizing an iframe that could be dependent on the</div><div>
event handler setting some data field.  this kind of thing is probably even</div><div>less common in the cross-origin case.</div></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">
&gt; Our approach to implementing implicit locking (if we must) will be to detect<br>
&gt; nested locking, and simply unlock the first held lock to basically prevent<br>
&gt; nested locking.  This way we don&#39;t have to know all of the cases where this<br>
&gt; can happen.<br>
<br>
</div>So is this the plan even for the WebDatabase API? I.e. a page starts a<br>
transaction, and thereby grab a lock on the database, and then call<br>
some function that requires the UA to grab another lock, will you at<br>
that point release the lock? And if so, will you commit or release the<br>
transaction?<br>
<div><div></div><div class="h5"><br></div></div></blockquote><div><br></div><div>no.  for database, we can just defer the second transaction.  this is what</div><div><div>i would like to be able to do with local storage, but i cannot since local</div>
<div>storage is synchronous.</div><div><br></div><div><br></div></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div><div class="h5">
&gt;&gt; &gt;&gt; &gt;&gt; But, as imperfect as the current API is, I think the following is a<br>
&gt;&gt; &gt;&gt; &gt;&gt; decent way forward:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; * Allow pages that want the convenience of localStorage to use it.<br>
&gt;&gt; &gt;&gt; &gt;&gt; For<br>
&gt;&gt; &gt;&gt; &gt;&gt; multi-process browsers this will mean poor UI *for pages that use<br>
&gt;&gt; &gt;&gt; &gt;&gt; localStorage*. Especially when said pages hold on to localStorage<br>
&gt;&gt; &gt;&gt; &gt;&gt; for<br>
&gt;&gt; &gt;&gt; &gt;&gt; a long time.<br>
&gt;&gt; &gt;&gt; &gt;&gt; * Add alternative APIs that don&#39;t suffer from the same problems.<br>
&gt;&gt; &gt;&gt; &gt;&gt; More<br>
&gt;&gt; &gt;&gt; &gt;&gt; below.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; In addition, this argument assumes that Microsoft (and other<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; UAs)<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; will<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; implement the structured clone version of LocalStorage.  Has<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; anyone<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; (or<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; can<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; anyone) from Microsoft comment on this?<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; Given that I&#39;ve never heard microsoft commit to a webstandard,<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; ever,<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; I<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; doubt that we&#39;ll hear anything here. Or that the lack of hearing<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; anything means we can draw any conclusions.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; This is not a small feature to add.  Yes, it&#39;s smaller than<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; creating<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; a<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; new<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; storage mechanism (that everyone is willing to adopt), but I<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; still<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; think<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; that&#39;s what we should be looking at.  Rather than polishing a<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; &gt; turd.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; I do think that localStorage is a decent API that developers will<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; want<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; to, and should, use. I think looking into adding a async accessor<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; to<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; get a storage object so that people can use an localStorage-like<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; API<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; while avoiding risks of blocking. This would also allow sharing<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; data<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; between worker threads and the main window.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; i think the async callback to get a storage object is an<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; improvement,<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; but<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; i&#39;m not sure that it addresses all of the problems.  for example,<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; if<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; a<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; worker<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; wants to read values from storage, compute, and then put a value<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; into<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; storage, it would probably do all of this from the storage<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; callback.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;  that<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; would result in holding the lock for a long time, which would lock<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; out<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; any<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; other threads, including non-worker threads.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; the problem here is that localStorage is a pile of global<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; variables.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;  we<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; are<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; trying to give people global variables without giving them tools<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; to<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; synchronize<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; access to them.  the claim i&#39;ve heard is that developers are not<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; savy<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; enough<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; to use those tools properly.  i agree that developers tend to use<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; tools<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; without<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; fully understanding them.  ok, but then why are we giving them<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; global<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; variables?<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; there has to be a better answer.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; I actually described an potential solution in the thread on worker<br>
&gt;&gt; &gt;&gt; &gt;&gt; storage.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; The problem you describe is a worker holding on the the storage for<br>
&gt;&gt; &gt;&gt; &gt;&gt; an<br>
&gt;&gt; &gt;&gt; &gt;&gt; very long (indefinite) time, thereby locking out other<br>
&gt;&gt; &gt;&gt; &gt;&gt; threads/windows<br>
&gt;&gt; &gt;&gt; &gt;&gt; from accessing the same storage area. This seems inevitable if we<br>
&gt;&gt; &gt;&gt; &gt;&gt; want<br>
&gt;&gt; &gt;&gt; &gt;&gt; to prevent race conditions while at the same time not forcing the<br>
&gt;&gt; &gt;&gt; &gt;&gt; complexities of locks onto web developers. The WebDatabase API<br>
&gt;&gt; &gt;&gt; &gt;&gt; suffers<br>
&gt;&gt; &gt;&gt; &gt;&gt; from exactly the same problem.<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; Hmm... are you saying that from the SQLStatementCallback used to read<br>
&gt;&gt; &gt;&gt; &gt; some data out of the database, you might compute on that data, and<br>
&gt;&gt; &gt;&gt; &gt; then<br>
&gt;&gt; &gt;&gt; &gt; issue an executeSql call to write a computed result, and that in this<br>
&gt;&gt; &gt;&gt; &gt; scenario,<br>
&gt;&gt; &gt;&gt; &gt; the fact that it is the same transaction means that other threads are<br>
&gt;&gt; &gt;&gt; &gt; locked<br>
&gt;&gt; &gt;&gt; &gt; out of accessing the same database?  I hadn&#39;t considered chaining<br>
&gt;&gt; &gt;&gt; &gt; executeSql<br>
&gt;&gt; &gt;&gt; &gt; calls like this to keep the transaction alive.  Hmm...<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Indeed.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; However, we can lessen the problem. By adding multiple storage<br>
&gt;&gt; &gt;&gt; &gt;&gt; areas,<br>
&gt;&gt; &gt;&gt; &gt;&gt; we can allow a worker to use one storage area, while allowing other<br>
&gt;&gt; &gt;&gt; &gt;&gt; parties to simultaneously use other storage areas. This way, if a<br>
&gt;&gt; &gt;&gt; &gt;&gt; worker and a window aren&#39;t sharing data at all, they never get in<br>
&gt;&gt; &gt;&gt; &gt;&gt; the<br>
&gt;&gt; &gt;&gt; &gt;&gt; way of each other.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; So a very simplistic design would be something like the following:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; getStorageArea(name, callback)<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; when called will asynchronously call the callback parameter once the<br>
&gt;&gt; &gt;&gt; &gt;&gt; storage area named by the first parameter becomes available. The<br>
&gt;&gt; &gt;&gt; &gt;&gt; callback receives the storage area as an argument. We would also<br>
&gt;&gt; &gt;&gt; &gt;&gt; have<br>
&gt;&gt; &gt;&gt; &gt;&gt; the function<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; getMultipleStorageAreas(names, callback)<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; Same as above, but names is an array of strings indicating multiple<br>
&gt;&gt; &gt;&gt; &gt;&gt; storage areas that need to be acquired before the callback is<br>
&gt;&gt; &gt;&gt; &gt;&gt; called.<br>
&gt;&gt; &gt;&gt; &gt;&gt; The callback receives all the areas in an array as an argument. This<br>
&gt;&gt; &gt;&gt; &gt;&gt; function allows transferring data between multiple storage areas<br>
&gt;&gt; &gt;&gt; &gt;&gt; without risking racing.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; There&#39;s several problems with this, such as the names are sort of<br>
&gt;&gt; &gt;&gt; &gt;&gt; crappy, and that getting storage areas an array isn&#39;t very friendly.<br>
&gt;&gt; &gt;&gt; &gt;&gt; However you get the basic idea.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; We don&#39;t even need to use Storage objects for this. In fact, I hope<br>
&gt;&gt; &gt;&gt; &gt;&gt; mozilla will in a not too distant future come up with an alternative<br>
&gt;&gt; &gt;&gt; &gt;&gt; proposal to the WebDatabase SQL API. Something like this might fit<br>
&gt;&gt; &gt;&gt; &gt;&gt; into such a proposal as I think that&#39;ll have multiple separate<br>
&gt;&gt; &gt;&gt; &gt;&gt; storage<br>
&gt;&gt; &gt;&gt; &gt;&gt; areas anyway.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; / Jonas<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; Maybe we should just invent a similar transaction method for<br>
&gt;&gt; &gt;&gt; &gt; name/value<br>
&gt;&gt; &gt;&gt; &gt; storage?  Wouldn&#39;t that be better than inventing a new idiom?<br>
&gt;&gt; &gt;&gt; &gt;  Ideally,<br>
&gt;&gt; &gt;&gt; &gt; we&#39;d also make reads and writes on storage be asynchronous.  The<br>
&gt;&gt; &gt;&gt; &gt; transaction would then be usable to hold the lock across multiple<br>
&gt;&gt; &gt;&gt; &gt; asynchronous reads and writes.  Since local storage is backed by<br>
&gt;&gt; &gt;&gt; &gt; disk,<br>
&gt;&gt; &gt;&gt; &gt; it seems like a more ideal local storage API would not<br>
&gt;&gt; &gt;&gt; &gt; require synchronous<br>
&gt;&gt; &gt;&gt; &gt; filesystem access.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Not quite following what you&#39;re suggesting, but there&#39;s lots of ways<br>
&gt;&gt; &gt;&gt; to design this. The critical part is to allow grabbing (with<br>
&gt;&gt; &gt;&gt; associated locking) of just a subset of the available storage space.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; / Jonas<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; I was suggesting that we only provide asynchronous getItem / setItem<br>
&gt;&gt; &gt; calls,<br>
&gt;&gt; &gt; where<br>
&gt;&gt; &gt; each call is parameterized by a transaction.  This is how database<br>
&gt;&gt; &gt; works.<br>
&gt;&gt;<br>
&gt;&gt; Not quite sure I follow your proposal. How would you for example<br>
&gt;&gt; increase the value of a property by one without risking race<br>
&gt;&gt; conditions? Or keep two values in different properties in sync? I.e.<br>
&gt;&gt; so that if you update one always update the other, so that they never<br>
&gt;&gt; have different values.<br>
&gt;&gt;<br>
&gt;&gt; / Jonas<br>
&gt;<br>
&gt;<br>
&gt; Easy.  Just like with database, the transaction is the storage lock.  Any<br>
&gt; storage<br>
&gt; operation performed on that transaction are done atomically.  However, all<br>
&gt; storage<br>
&gt; operations are asynchronous.  You basically string together asynchronous<br>
&gt; storage<br>
&gt; operations by using the same transaction for each.<br>
&gt; We could add methods to get/set multiple items at once to simplify life for<br>
&gt; the coder.<br>
<br>
</div></div>I think I still don&#39;t understand your proposal, could you give some<br>
code examples?<br><font class="Apple-style-span" color="#888888"><br></font></blockquote><div><br></div><div><br></div><div><div>ripping off database:</div><div><br></div><div>interface ValueStorage {</div><div>  void transaction(in DOMString namespace, in ValueStorageTransactionCallback callback);</div>
<div>};</div><div>interface ValueStorageTransactionCallback {</div><div>  void handleEvent(in ValueStorageTransaction transaction);</div><div>};</div><div>interface ValueStorageTransaction {</div><div>  void readValue(in DOMString name, in ValueStorageReadCallback callback);</div>
<div>  void writeValue(in DOMString name, in DOMString value);</div><div>};</div><div>interface ValueStorageReadCallback {</div><div>  void handleEvent(in ValueStorageTransaction transaction, in DOMString value);</div><div>
};</div><div><br></div><div>then, to use these interfaces, you could implement thread-safe increment:</div><div><br></div><div>window.localStorage.transaction(&quot;slice&quot;, function(transaction) {</div><div>  transaction.readValue(&quot;foo&quot;, function(transaction, fooValue) {</div>
<div>    transaction.writeValue(&quot;foo&quot;, ++fooValue);</div><div>  })</div><div>})</div><div><br></div><div>to fetch multiple values, you could do this:</div><div><br></div><div>var values = [];</div><div>var numValues = 10;</div>
<div>function readNextValue(transaction) {</div><div>  if (values.length == numValues)</div><div>   return;  // done!</div><div>  var index = values.length;</div><div>  transaction.readValue(&quot;value&quot; + index, function(transaction, value) {</div>
<div>    values.push(value);</div><div>    readNextValue(transaction);</div><div>  })</div><div>}</div><div>window.localStorage.transaction(&quot;slice&quot;, readNextValue);</div><div><br></div><div>This has the property that all IO is non-blocking and the &quot;lock&quot; is held only</div>
<div>for a very limited scope.  The programmer is however free to extend the</div><div>life of the lock as needed.</div><div><br></div><div>-Darin</div></div><div> </div></div>