<div class="gmail_quote">On Wed, Sep 16, 2009 at 2: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 Wed, Sep 16, 2009 at 12:58 PM, Drew Wilson <<a href="mailto:atwilson@google.com">atwilson@google.com</a>> wrote:<br>
> I'm saying that an async API is overkill and unwieldy if all you need is<br>
> WorkerLocalStorage.<br>
> If you're going to route your localstorage access through an async API<br>
> anyway, then you might as well proxy it to the parent page - there's very<br>
> little advantage to doing it otherwise, other than access to lexically<br>
> scoped resources from within your callback.<br>
<br>
</div>Actually, there's a pretty big difference. With the current state of<br>
affairs, if a worker wants to make a computation based on values in<br>
the localStorage, and store the result in localStorage, this is<br>
extremely hard.<br>
<br>
For example, say that a worker want to perform the following operation:<br>
<br>
localStorage.result = F(localStorage.n);<br>
<br>
where F(n) is the n:th value in the Fibonacci sequence.<br>
<br>
To do this today the worker would first have to call the main window<br>
to get the localStoreage.n value. It could then calculate the result<br>
of F(localStorage.n). It would then send a message to the main window<br>
to store the result in localStorage.result. However in the meantime<br>
localStorage.n might have changed, which causes an inconsistent state.<br>
<br>
So instead the worker has to send both the value of localStorage.n as<br>
well as the result to the window. The window can then check if<br>
localStorage.n has changed. If it has changed, the window has to send<br>
the new value back to the worker, and then the worker has to redo its<br>
calculation.<br>
<br>
This has several problems. It's bug prone since the developer might<br>
not realize the race condition. It's very hard to do correctly. And<br>
even when done correctly risks wasting a lot of cycles.<br>
<br>
An alternative solution is to do all calculations in the main window,<br>
which has synchronous access to localStorage. But the whole point of a<br>
worker is to avoid having to do heavy work in the window.<br>
<br>
However, with the solution Jeremy proposed, calculating the above<br>
algorithm can be done in the worker after the worker while the worker<br>
is inside the callback and thus have synchronous access to<br>
localStorage.<br>
<br>
Say that instead of calculating Fibonacci numbers, we were storing a<br>
database of emails in localStorage, and using a worker to synchronize<br>
that database to a server. In this case it seems extermely complex to<br>
have to communicate asynchronously through the window and deal with<br>
race conditions where the user is modifying the email database at the<br>
same time.<br></blockquote><div><br></div><div>True.</div><div><br></div><div>The problem is that some page from the same origin might also try to access LocalStorage. If it does, it'll block the entire event loop until the worker is finished. I can't think of how to "fix" this in a way that's not racy. My originally proposal was written in the hope that developers would be more cautious since they're doing things inside an async callback, but the more I think about it, the more I think this isn't realistic.</div>
<div><br></div><div>I think we have 3 options:</div><div><br></div><div>1) Create a LocalStorage like API that can only be accessed in an async way via pages (kind of like WebDatabase).</div><div><br></div><div>2) Remove any atomicity/consistency guarantees from synchronous LocalStorage access within pages (like IE8 currently does) and add an async interface for when pages do need atomicity/consistency.</div>
<div><br></div><div>3) Come up with a completely different storage API that all the browser vendors are willing to implement that only allows Async access from within pages. WebSimpleDatabase might be a good starting point for this.</div>
<div><br></div><div><br></div><div>1 is probably the simplest to implement, but it seems pretty hacky and it's likely not powerful enough for many advanced web apps (offline web mail would be an example). If we do 2, many (most?) web developers will just use the sync interface and write racy apps. 3 will take the longest time to do, but is definitely the best long term solution.</div>
<div><br></div><div><br></div><div>Do others agree with my list? What's the best option out of these? Honestly, I'm kind of leaning towards 3 at this point.</div><div><br></div><div>J</div></div>