<br><br><div class="gmail_quote">On Fri, Oct 2, 2009 at 8:08 PM, Jonas Sicking <span dir="ltr"><jonas@sicking.cc></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 Wed, Sep 30, 2009 at 10:11 PM, Darin Fisher <span dir="ltr"><<a href="mailto:darin@chromium.org" target="_blank">darin@chromium.org</a>></span> wrote:<br></div></div><div class="gmail_quote">
<div><div></div><div class="h5"><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<div class="gmail_quote"><div><div></div><div>On Tue, Sep 29, 2009 at 11:48 PM, Jonas Sicking <span dir="ltr"><jonas@sicking.cc></span> wrote:<br><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<div><div></div><div>On Tue, Sep 29, 2009 at 12:19 AM, Darin Fisher <<a href="mailto:darin@chromium.org" target="_blank">darin@chromium.org</a>> wrote:<br>
> On Thu, Sep 24, 2009 at 11:57 PM, Jonas Sicking <jonas@sicking.cc> wrote:<br>
>><br>
>> On Thu, Sep 24, 2009 at 9:04 PM, Darin Fisher <<a href="mailto:darin@chromium.org" target="_blank">darin@chromium.org</a>> wrote:<br>
>> > On Thu, Sep 24, 2009 at 4:43 PM, Jonas Sicking <jonas@sicking.cc> wrote:<br>
>> >><br>
>> >> On Thu, Sep 24, 2009 at 10:52 AM, Darin Fisher <<a href="mailto:darin@chromium.org" target="_blank">darin@chromium.org</a>><br>
>> >> wrote:<br>
>> >> > On Thu, Sep 24, 2009 at 10:40 AM, Jonas Sicking <jonas@sicking.cc><br>
>> >> > wrote:<br>
>> >> >><br>
>> >> >> On Thu, Sep 24, 2009 at 1:17 AM, Darin Fisher <<a href="mailto:darin@chromium.org" target="_blank">darin@chromium.org</a>><br>
>> >> >> wrote:<br>
>> >> >> > On Thu, Sep 24, 2009 at 12:20 AM, Jonas Sicking <jonas@sicking.cc><br>
>> >> >> > wrote:<br>
>> >> >> >><br>
>> >> >> >> On Wed, Sep 23, 2009 at 10:19 PM, Darin Fisher<br>
>> >> >> >> <<a href="mailto:darin@chromium.org" target="_blank">darin@chromium.org</a>><br>
>> >> >> >> wrote:<br>
><br>
> ... snip ...<br>
><br>
>><br>
>> >> >> >> > multi-core is the future. what's the opposite of fine-grained<br>
>> >> >> >> > locking?<br>
>> >> >> >> > it's not good ;-)<br>
>> >> >> >> > the implicit locking mechanism as spec'd is super lame.<br>
>> >> >> >> > implicitly<br>
>> >> >> >> > unlocking under<br>
>> >> >> >> > mysterious-to-the-developer circumstances! how can that be a<br>
>> >> >> >> > good<br>
>> >> >> >> > thing?<br>
>> >> >> >> > storage.setItem("y",<br>
>> >> >> >> > function_involving_implicit_unlocking(storage.getItem("x")));<br>
>> >> >> >><br>
>> >> >> >> I totally agree on all points. The current API has big<br>
>> >> >> >> imperfections.<br>
>> >> >> >> However I haven't seen any workable counter proposals so far, and<br>
>> >> >> >> I<br>
>> >> >> >> honestly don't believe there are any as long as our goals are:<br>
>> >> >> >><br>
>> >> >> >> * Don't break existing users of the current implementations.<br>
>> >> >> >> * Don't expose race conditions to the web.<br>
>> >> >> >> * Don't rely on authors getting explicit locking mechanisms<br>
>> >> >> >> right.<br>
>> >> >> >><br>
>> >> >> ><br>
>> >> >> > The current API exposes race conditions to the web. The implicit<br>
>> >> >> > dropping of the storage lock is that. In Chrome, we'll have to<br>
>> >> >> > drop<br>
>> >> >> > an existing lock whenever a new lock is acquired. That can happen<br>
>> >> >> > due to a variety of really odd cases (usually related to nested<br>
>> >> >> > loops<br>
>> >> >> > or nested JS execution), which will be difficult for developers to<br>
>> >> >> > predict, especially if they are relying on third-party JS<br>
>> >> >> > libraries.<br>
>> >> >> > This issue seems to be discounted for reasons I do not understand.<br>
>> >> >><br>
>> >> >> I don't believe we've heard about this before, so that would be the<br>
>> >> >> reason it hasn't been taken into account.<br>
>> >> >><br>
>> >> >> So you're saying that chrome would be unable implement the current<br>
>> >> >> storage mutex as specified in spec? I.e. one that is only released<br>
>> >> >> at<br>
>> >> >> the explicit points that the spec defines? That seems like a huge<br>
>> >> >> problem.<br>
>> >> ><br>
>> >> > No, no... my point is that to the application developer, those<br>
>> >> > "explicit"<br>
>> >> > points will appear quite implicit and mysterious. This is why I<br>
>> >> > called<br>
>> >> > out third-party JS libraries. One day, a function that you are using<br>
>> >> > might transition to scripting a plugin, which might cause a nested<br>
>> >> > loop, which could then force the lock to be released. As a<br>
>> >> > programmer,<br>
>> >> > the unlocking is not explicit or predictable.<br>
>> >><br>
>> >> Ah, indeed, this is a problem. However the unfortunate fact remains<br>
>> >> that so far no other workable solution has been proposed.<br>
>> ><br>
>> > OK, so we agree that the current solution doesn't meet the goals you<br>
>> > stated above :-(<br>
>><br>
>> 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's unlikely that they will do<br>
>> so correctly.<br>
><br>
> I thought the point of not having lock APIs was that users shouldn't have<br>
> to understand locks ;-) The issue I've raised here is super subtle. We<br>
> have not succeeded in avoiding subtlety!<br>
<br>
</div></div>I think we're mostly in agreement. What I'm not sure about is what you<br>
are proposing we do with localStorage? Remove it from the spec? Change<br>
the API? Something else?<br>
<div><div></div><div><br></div></div></blockquote><div><br></div></div></div><div>I'm glad we agree.</div><div><br></div><div>I'm not sure what we should do. It seems like there is a "legacy API"</div>
<div>
argument for sticking with the current proposal even though it is flawed and</div><div>HTML5 is not yet final. (It has also not been implemented by browsers for</div><div>very long.) Stated that way, it sounds like a weak argument for preserving</div>
<div>the API as is, and we should just fix it to be better.</div><div><br></div><div>My understanding is that removal is not a popular position. However, given</div><div>that more browsers are moving to be multi-process, I have to say that I'm a</div>
<div>bit surprised there isn't more support for ditching the current localStorage</div><div>API.</div></div></blockquote></div></div><div><br>You're preaching to the choir :) I'd recommend talking to apple and microsoft directly. I don't know what their plans are regarding all this. <br>
</div></div></blockquote><div><br></div><div>Fair enough :-)</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="gmail_quote">
<div>
</div><div><div></div><div class="h5"><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex"><div class="gmail_quote"><div><div><div></div><div> </div>
<blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<div><div>
>> >> > Moreover, there are other examples which have been discussed on the<br>
>> >> > list. There are some DOM operations that can result in a frame<br>
>> >> > receiving<br>
>> >> > a DOM event synchronously. That can result in a nesting of storage<br>
>> >> > locks,<br>
>> >> > which can force us to have to implicitly unlock the outermost lock to<br>
>> >> > avoid<br>
>> >> > deadlocks. Again, the programmer will have very poor visibility into<br>
>> >> > when<br>
>> >> > these things can happen.<br>
>> >><br>
>> >> So far I don't think it has been shown that these events need to be<br>
>> >> synchronous. They all appear to be asynchronous in gecko, and in the<br>
>> >> case of different-origin frames, I'm not even sure there's a way for<br>
>> >> pages to detect if the event was fired asynchronously or not.<br>
>> ><br>
>> > IE and WebKit dispatch some of them synchronously. It's hard to say<br>
>> > which<br>
>> > is correct or if it causes any web compat isues. I'm also not sure that<br>
>> > we<br>
>> > have covered all of the cases.<br>
>><br>
>> It still seems to me that it's extremely unlikely that pages depend on<br>
>> cross origin events to fire synchronously. I can't even think of a way<br>
>> to test if a browser dispatches these events synchronously or not. Can<br>
>> you?<br>
><br>
> i agree that it seems uncommon. maybe there could be some odd app that<br>
> does something after resizing an iframe that could be dependent on the<br>
> event handler setting some data field. this kind of thing is probably even<br>
> less common in the cross-origin case.<br>
<br>
</div></div>But how would you read that data field in the cross-origin frame? I<br>
think it might be possible, but extremely hard.<br>
<div><div></div><div><br></div></div></blockquote><div><br></div></div></div><div>Yeah.</div><div><br></div><div>My concern is simply that I cannot prove that I don't have to worry about this</div><div>problem. Future web APIs might also inadvertently make matters worse.</div>
</div></blockquote></div></div><div><br>I agree it's not ideal, but at the same time I don't think that not allowing synchronous cross-origin APIs is a huge burden. You campaigned heavily against that when we were designing postMessage for wholly other reasons. I would imagine those reasons will hole true no matter what.<br>
</div></div></blockquote><div><br></div><div>Agreed. That's a good point. In that case, I was concerned about stack depth. The same issue might apply here. Hmm...</div><div><br></div><div><br></div><div>...snip...</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex"><div><div><br>
>> >> Not quite sure I follow your proposal. How would you for example<br>
>> >> increase the value of a property by one without risking race<br>
>> >> conditions? Or keep two values in different properties in sync? I.e.<br>
>> >> so that if you update one always update the other, so that they never<br>
>> >> have different values.<br>
>> >><br>
>> >> / Jonas<br>
>> ><br>
>> ><br>
>> > Easy. Just like with database, the transaction is the storage lock.<br>
>> > Any<br>
>> > storage<br>
>> > operation performed on that transaction are done atomically. However,<br>
>> > all<br>
>> > storage<br>
>> > operations are asynchronous. You basically string together asynchronous<br>
>> > storage<br>
>> > operations by using the same transaction for each.<br>
>> > We could add methods to get/set multiple items at once to simplify life<br>
>> > for<br>
>> > the coder.<br>
>><br>
>> I think I still don't understand your proposal, could you give some<br>
>> code examples?<br>
>><br>
><br>
><br>
> ripping off database:<br>
> interface ValueStorage {<br>
> void transaction(in DOMString namespace, in<br>
> ValueStorageTransactionCallback callback);<br>
> };<br>
> interface ValueStorageTransactionCallback {<br>
> void handleEvent(in ValueStorageTransaction transaction);<br>
> };<br>
> interface ValueStorageTransaction {<br>
> void readValue(in DOMString name, in ValueStorageReadCallback callback);<br>
> void writeValue(in DOMString name, in DOMString value);<br>
> };<br>
> interface ValueStorageReadCallback {<br>
> void handleEvent(in ValueStorageTransaction transaction, in DOMString<br>
> value);<br>
> };<br>
> then, to use these interfaces, you could implement thread-safe increment:<br>
> window.localStorage.transaction("slice", function(transaction) {<br>
> transaction.readValue("foo", function(transaction, fooValue) {<br>
> transaction.writeValue("foo", ++fooValue);<br>
> })<br>
> })<br>
> to fetch multiple values, you could do this:<br>
> var values = [];<br>
> var numValues = 10;<br>
> function readNextValue(transaction) {<br>
> if (values.length == numValues)<br>
> return; // done!<br>
> var index = values.length;<br>
> transaction.readValue("value" + index, function(transaction, value) {<br>
> values.push(value);<br>
> readNextValue(transaction);<br>
> })<br>
> }<br>
> window.localStorage.transaction("slice", readNextValue);<br>
> This has the property that all IO is non-blocking and the "lock" is held<br>
> only<br>
> for a very limited scope. The programmer is however free to extend the<br>
> life of the lock as needed.<br>
<br>
</div></div>What do you mean by that the "lock" is held for only a very limited<br>
scope? You still want to prevent modifications for as long as the<br>
transaction is being used right? I.e. no modifications can happen<br>
between the read and the write in the first example, and between the<br>
different reads in the second.<br></blockquote><div><br></div></div></div><div>Yes. I only meant that the programmer doesn't have to call a special</div><div>function to close the transaction. It closes by virtue of the last handleEvent</div>
<div>call referring to the transaction returning.</div></div></blockquote></div></div><div><br>So wouldn't you implement this transaction using a lock? To prevent other pages from accessing the localStorage?<br><br></div>
</div></blockquote><div><br></div><div>Yes, but it wouldn't need to be a normal mutex if that's what you mean. You could just defer callbacks until the transaction completes. It is purely asynchronous locking.</div>
<div><br></div><div>-Darin</div></div>