[whatwg] Polling APIs in JavaScript vs Callbacks

Gregg Tavares gman at google.com
Thu Feb 7 16:24:18 PST 2013


 Anyone have time to give me some advice, tips, pointers?

In the next WebGL we have Query/Sync objects. In C/C++ land the user can
insert some drawing commands that will happen asynchronously on the GPU.
They can also insert a query. They can then poll that query (did this
finish?).

We'd like to expose that to JavaScript. I've been pushing to making it a
callback in JavaScript rather than polling. Most graphics developers I talk
to hate this idea.

My assumptions have been

(a) polling is kind of maybe not allowed in JS (though I have no proof,
only heresy)

Are there any "rules" or things in the spec that make polling apis
untenable?


(b) polling is often error prone and those errors can be avoided using
callbacks and I'm assuming designing an API that is hard or impossible to
use wrong is a good thing.

To give an example, in GL I can render in 2 threads. Let's say in one
thread I'm rendering to a texture and in the other thread I'd like to use
that texture to render something else.

I can insert a query in the first thread, and poll that query in the second
thread. When the query says the texture is ready the second thread can
render with it.

The problem is, if I forget to query things won't fail I'll just get the
wrong results. But I might not. It might be that rendering on thread #1
takes 1ms and it takes 2ms before thread 2 tries to render so things just
appear to work, no queries needed. But then something (another tab, another
app) slows the the system down. Thread #1 takes 4ms now and Thread #2 which
is just assuming things take 2ms renders and sees old or half rendered
results.

We can encapsulate some of this. In WebGL we can require that the texture
being used in both threads be a wrapped object, a SharedTexture, and we can
require SharedTextures can be used in only 1 thread at a time. You acquire
and release it on a particular thread. And so now comes the issue:

Should acquire block, poll or use a callback

block = evil

poll has the issue that I can try to use the texture even when I haven't
acquired it. See the example above. It allows not polling and assuming the
texture will be available. That might work most of the time but on some
machine or under certain circumstances the acquire will fail. Apps that
forget to check for success because the API let them ignore failure will
then fail in strange and random ways. It basically exposes race conditions

callback seems to make it much harder to use wrong. You get a callback when
the texture has been acquired. Now you can't use it without calling acquire
period.

But. that comes back to (a) above. Move devs I've talked to really don't
want to use callbacks. They're all good devs and they know what they're
doing and they don't want to deal with what they consider callback/closure
hell. Especially when they need to acquire multiple things at once.

I'm in the callback camp. (1) to protect programmers from mistakes they
won't find until the exceptional happens and (2) because I'm under the
impression that browser vendors would say "no" to polling. But, maybe it
doesn't matter and polling is fine.

note: this issue already exists in the Web API today with images. Example:

img.src = "someimage.jpg"
setTimeout(function() {
   ctx.drawImage(img, 0, 0);
}, 1000);

Assumes the image will be available in 1 second which may or may not be
true. The API could have been designed to make this much harder to get
wrong (though not impossible). If you had get some kind of ImageHandle to
call drawImage and you could only get that ImageHandle in the 'load' event
of an image

Images are not quite analogous though as there is no polling built in
polling on an image to find out if it's finished.


More information about the whatwg mailing list