Re: Sync IO APIs in Shared Workers

On Thu, Nov 21, 2013 at 8:33 PM, Jonas Sicking <jonas@sicking.cc> wrote:

> 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.
>

The only relevant thing I can dig out of [1] can be summarized much more
simply: "we need a way to interrupt synchronous calls".

It'd be tricky to allow interruption while still leading to robust code,
but I think it's worth exploring.  In principle it violates the "don't
expose asynchronous behavior" principle, but in reality, asynchronous
programming with messages coming from other threads does the same thing.
We'd need to make sure it's very clear which calls can be interrupted, to
avoid EINTR-like problems.

But, we should explore the use cases more thoroughly first, to see if this
is really needed.  An alternative is to just terminate() the whole worker
and start a new one.  That's not very elegant, but it's very simple and
robust: you don't end up with synchronous APIs throwing exceptions
unexpectedly and worker code having to clean up after it.  If the work is
expensive enough that you need to cancel it, the cost of spinning up a new
worker is negligible.  Are there use cases where this doesn't work?

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.
>

(This isn't an argument against sync APIs.  The same thing will happen with
async APIs if the page fails to give appropriate feedback to the user.)


> 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.


I think it's wishful thinking.  My experience is that async programming is
inherently less convenient than sync programming.

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.
>

(I'd use a MessagePort, eg. setCancellationPort(port), since the parent
thread shouldn't be special.)


> 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.
>

http://lists.w3.org/Archives/Public/public-webapps/2010OctDec/1075.html
http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0967.html

The proposal is to allow polling a MessagePort, retrieving the next message
without having to return to the event loop.  I think that's useful to allow
number crunching workers to periodically check for new information, without
having to return all the way to the event loop.  It never got traction,
though.

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.
>

This will just make people proxy messages from the shared worker to a
dedicated worker, so nothing would change.  I don't think making shared
workers more different from dedicated workers than they have to be makes
much sense.

-- 
Glenn Maynard

Received on Friday, 22 November 2013 15:55:14 UTC