[whatwg] Structured clone algorithm on LocalStorage
Jonas Sicking
jonas at sicking.cc
Fri Oct 2 21:43:51 PDT 2009
>
> >> >> > Moreover, there are other examples which have been discussed on
>>>> the
>>>> >> >> > list. There are some DOM operations that can result in a frame
>>>> >> >> > receiving
>>>> >> >> > a DOM event synchronously. That can result in a nesting of
>>>> storage
>>>> >> >> > locks,
>>>> >> >> > which can force us to have to implicitly unlock the outermost
>>>> lock to
>>>> >> >> > avoid
>>>> >> >> > deadlocks. Again, the programmer will have very poor visibility
>>>> into
>>>> >> >> > when
>>>> >> >> > these things can happen.
>>>> >> >>
>>>> >> >> So far I don't think it has been shown that these events need to
>>>> be
>>>> >> >> synchronous. They all appear to be asynchronous in gecko, and in
>>>> the
>>>> >> >> case of different-origin frames, I'm not even sure there's a way
>>>> for
>>>> >> >> pages to detect if the event was fired asynchronously or not.
>>>> >> >
>>>> >> > IE and WebKit dispatch some of them synchronously. It's hard to
>>>> say
>>>> >> > which
>>>> >> > is correct or if it causes any web compat isues. I'm also not sure
>>>> that
>>>> >> > we
>>>> >> > have covered all of the cases.
>>>> >>
>>>> >> It still seems to me that it's extremely unlikely that pages depend
>>>> on
>>>> >> cross origin events to fire synchronously. I can't even think of a
>>>> way
>>>> >> to test if a browser dispatches these events synchronously or not.
>>>> Can
>>>> >> you?
>>>> >
>>>> > i agree that it seems uncommon. maybe there could be some odd app
>>>> that
>>>> > does something after resizing an iframe that could be dependent on the
>>>> > event handler setting some data field. this kind of thing is probably
>>>> even
>>>> > less common in the cross-origin case.
>>>>
>>>> But how would you read that data field in the cross-origin frame? I
>>>> think it might be possible, but extremely hard.
>>>>
>>>>
>>> Yeah.
>>>
>>> My concern is simply that I cannot prove that I don't have to worry about
>>> this
>>> problem. Future web APIs might also inadvertently make matters worse.
>>>
>>
>> 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.
>>
>
> Agreed. That's a good point. In that case, I was concerned about stack
> depth. The same issue might apply here. Hmm...
>
As far as I can see it does.
>
> ...snip...
>
>>
>>>> >> >> Not quite sure I follow your proposal. How would you for example
>>>> >> >> increase the value of a property by one without risking race
>>>> >> >> conditions? Or keep two values in different properties in sync?
>>>> I.e.
>>>> >> >> so that if you update one always update the other, so that they
>>>> never
>>>> >> >> have different values.
>>>> >> >>
>>>> >> >> / Jonas
>>>> >> >
>>>> >> >
>>>> >> > Easy. Just like with database, the transaction is the storage
>>>> lock.
>>>> >> > Any
>>>> >> > storage
>>>> >> > operation performed on that transaction are done atomically.
>>>> However,
>>>> >> > all
>>>> >> > storage
>>>> >> > operations are asynchronous. You basically string together
>>>> asynchronous
>>>> >> > storage
>>>> >> > operations by using the same transaction for each.
>>>> >> > We could add methods to get/set multiple items at once to simplify
>>>> life
>>>> >> > for
>>>> >> > the coder.
>>>> >>
>>>> >> I think I still don't understand your proposal, could you give some
>>>> >> code examples?
>>>> >>
>>>> >
>>>> >
>>>> > ripping off database:
>>>> > interface ValueStorage {
>>>> > void transaction(in DOMString namespace, in
>>>> > ValueStorageTransactionCallback callback);
>>>> > };
>>>> > interface ValueStorageTransactionCallback {
>>>> > void handleEvent(in ValueStorageTransaction transaction);
>>>> > };
>>>> > interface ValueStorageTransaction {
>>>> > void readValue(in DOMString name, in ValueStorageReadCallback
>>>> callback);
>>>> > void writeValue(in DOMString name, in DOMString value);
>>>> > };
>>>> > interface ValueStorageReadCallback {
>>>> > void handleEvent(in ValueStorageTransaction transaction, in
>>>> DOMString
>>>> > value);
>>>> > };
>>>> > then, to use these interfaces, you could implement thread-safe
>>>> increment:
>>>> > window.localStorage.transaction("slice", function(transaction) {
>>>> > transaction.readValue("foo", function(transaction, fooValue) {
>>>> > transaction.writeValue("foo", ++fooValue);
>>>> > })
>>>> > })
>>>> > to fetch multiple values, you could do this:
>>>> > var values = [];
>>>> > var numValues = 10;
>>>> > function readNextValue(transaction) {
>>>> > if (values.length == numValues)
>>>> > return; // done!
>>>> > var index = values.length;
>>>> > transaction.readValue("value" + index, function(transaction, value)
>>>> {
>>>> > values.push(value);
>>>> > readNextValue(transaction);
>>>> > })
>>>> > }
>>>> > window.localStorage.transaction("slice", readNextValue);
>>>> > This has the property that all IO is non-blocking and the "lock" is
>>>> held
>>>> > only
>>>> > for a very limited scope. The programmer is however free to extend
>>>> the
>>>> > life of the lock as needed.
>>>>
>>>> What do you mean by that the "lock" is held for only a very limited
>>>> scope? You still want to prevent modifications for as long as the
>>>> transaction is being used right? I.e. no modifications can happen
>>>> between the read and the write in the first example, and between the
>>>> different reads in the second.
>>>>
>>>
>>> Yes. I only meant that the programmer doesn't have to call a special
>>> function to close the transaction. It closes by virtue of the last
>>> handleEvent
>>> call referring to the transaction returning.
>>>
>>
>> So wouldn't you implement this transaction using a lock? To prevent other
>> pages from accessing the localStorage?
>>
>>
> 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.
>
So how is that then different from from using a Storage API, but only
letting you get a reference to the Storage object using a asynchronous API?
And of course not allowing the Storage object to be stored in a variable and
used outside the callback.
/ Jonas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/attachments/20091002/dc6f1587/attachment-0002.htm>
More information about the whatwg
mailing list