- From: Jonas Sicking <jonas@sicking.cc>
- Date: Tue, 15 Sep 2009 20:27:56 -0700
On Tue, Sep 15, 2009 at 6:56 PM, Jeremy Orlow <jorlow at chromium.org> wrote: > One possible solution is to?add an asynchronous callback interface for > LocalStorage into workers. ?For example: > function myCallback(localStorage) { > ??localStorage.accountBalance = localStorage.accountBalance + 100; > } > executeLocalStorageCallback(myCallback); ?// TODO: Make this name better > ?:-) > The interface is simple. ?You can only access localStorage via a callback. > ?Any use outside of the callback is illegal and would raise an exception. > ?The callback would acquire the storage mutex during execution, but the > worker's execution would not block during this time. ?Of course, it's still > possible for a poorly behaving worker to do large amounts of?computation?in > the callback, but hopefully the fact they're executing in a callback makes > the developer more aware of the problem. First off, I agree that not having localStorage in workers is a big problem that we need to address. If I were designing the localStorage interface today I would use the above interface that you suggest. Grabbing localStorage can only be done asynchronously, and while you're using it, no one else can get a reference to it. This way there are no race conditions, but also no way for anyone to have to lock. So one solution is to do that in parallel to the current localStorage interface. Let's say we introduce a 'clientStorage' object. You can only get a reference to it using a 'getClientStorage' function. This function is available both to workers and windows. The storage is separate from localStorage so no need to worry about the 'storage mutex'. There is of course a risk that a worker grabs on to the clientStorage and holds it indefinitely. This would result in the main window (or another worker) never getting a reference to it. However it doesn't affect responsiveness of that window, it's just that the callback will never happen. While that's not ideal, it seems like a smaller problem than any other solution that I can think of. And the WebDatabase interfaces are suffering from the same problem if I understand things correctly. There's a couple of other interesting things we could expose on top of this: First, a synchronous API for workers. We could allow workers to synchronously get a reference to clientStorage. If someone is currently using clientStorage then the worker blocks until the storage becomes available. We could either use a callback as the above, which blocks until the clientStorage is acquired and only holds the storage until the callback exists. Or we could expose clientStorage as a property which holds the storage until control is returned to the worker eventloop, or until some explicit release API is called. The latter would be how localStorage is now defined, with the important difference that localStorage exposes the synchronous API to windows. Second, allow several named storage areas. We could add an API like getNamedClientStorage(name, callback). This would allow two different workers to simultaneously store things in a storage areas, as long as they don't need to use the *same* storage area. It would also allow a worker and the main window to simultaneously use separate storage areas. However we need to be careful if we add both above features. We can't allow a worker to grab multiple storage areas at the same time since that could cause deadlocks. However with proper APIs I believe we can avoid that. / Jonas
Received on Tuesday, 15 September 2009 20:27:56 UTC