[whatwg] Structured clone algorithm on LocalStorage
Jonas Sicking
jonas at sicking.cc
Sat Oct 3 01:05:58 PDT 2009
On Fri, Oct 2, 2009 at 9:58 PM, Darin Fisher <darin at chromium.org> wrote:
> >> >> 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.
>>
>
> The difference is that storage IO is fully asynchronous in the API I
> proposed. It doesn't have to block the calling thread for reads. I think
> that is important.
>
> We should never design any APIs that involve synchronous IO (filesystem or
> network) from the main UI thread.
>
Ah, that's a different problem from what I thought you talked about
initially.
I wasn't part of the initial design-phase of this API. But as I understand
it, the idea was that it's expected that people will store small enough
amounts of information in localStorage that the database can be kept in
memory. Behind the scenes you can always write to disc asynchronously in
order to reduce risk of dataloss in case of crash.
I'm not sure if this is practical or not. I suspect that many times it won't
be. However even here a asynchronous getter would help since you can read in
the full database into memory at that point.
/ Jonas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/attachments/20091003/5c4150ba/attachment-0002.htm>
More information about the whatwg
mailing list