- From: Jonas Sicking <jonas@sicking.cc>
- Date: Thu, 21 Nov 2013 18:33:51 -0800
- To: Webapps WG <public-webapps@w3.org>
Hi all, There has been some amount of debate about the virtue of sync IO APIs in workers. Or sync APIs in workers in general. One of the arguments made against sync APIs in workers made in [1] is that even for workers, it is often important to keep code responsive in order to react to actions taken by the user. I.e. while locking up a worker thread for an extended period of time won't cause problems like stuttered scrolling or UI that doesn't visually react when you click them, you can still end up with apps that seem unresponsive since the main thread is waiting to get back an answer from a worker thread that is busy. I honestly don't know what the right answer is. On one hand I could definitely see code which does sync IO in a worker in order to search for local data as the user types in a textbox, for example to implement autocomplete. In such an instance it's very easy to accidentally create unresponsive UI since it's not possible to abort the current search when the user types another key. On the other hand, having a worker which uses sync IO to synchronize local data with data from a server can produce significantly simpler code than doing the same thing with async IO. And this worker might never need to react to user actions and thus it's no problem to not handle incoming messages with low latency. I also don't buy the argument that we can make async programming so convenient that there's little cost to async APIs compared to sync APIs. As we add convenience methods like task.js to make async code look like sync code, the more we're creating an environment where multiple code paths are running in parallel in the same heap. I.e. the more we make it look like C-style threading. Yes, the differences are there and they are important. But as the differences between async and sync code gets smaller, the hazards get more real. One thing that we so far have not seemed to consider is fixing the problems with sync code raised in [1] and elsewhere. We could enable sync IO APIs in workers while still allowing the worker thread to remain responsive to messages from the main thread. One solution is the API in [2]. Using that API the main thread can send a error-response to a sync request for IO before the IO has finished. Another solution would be to use real sync IO APIs, but expose an object in the parent thread which allows the parent to abort the current operation. Something else that could improve responsiveness while still allowing people to write synchronous code is the ability to check if there are pending messages on a channel without having to return to the event loop. That way the code can keep running until there's a message to process, and only return to the event loop when there is. I'm not sure if any of these ideas will work in practice. Or if they helpful but insufficient to solve the problem. More research is needed. The problem of unresponsive workers is arguably worse for SharedWorkers. For shared workers a long running request from one window will block processing for all windows. One possible action here would be to disallow sync APIs in shared workers for now. This way we can use dedicated workers as a test bed to see if sync APIs are a problem, and if they are, if that problem can be fixed. The only browser shipping SharedWorkers is Chrome (not sure if Opera does too?), so if the Blink developers are willing to remove it from there, then this would be doable. Firefox has an implementation of SharedWorkers too, but it's not yet shipping. I think we'd be willing to turn off sync APIs in them before shipping. [1] http://infrequently.org/2013/05/the-case-against-synchronous-worker-apis-2/ [2] http://lists.w3.org/Archives/Public/public-webapps/2013OctDec/0142.html / Jonas
Received on Friday, 22 November 2013 02:34:54 UTC