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