[whatwg] LocalStorage in workers

Jonas Sicking jonas at sicking.cc
Tue Sep 15 20:27:56 PDT 2009


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


More information about the whatwg mailing list