Why does the Chrome extension API consist mostly of callbacks? - google-chrome

This is just out of curiosity, as I program games for a living, not web applications.
What is the reason that the Chrome extension API (chrome.* family) consists almost entirely of callback setters? I'm talking about this programming model that at first sight appears to be abusing closures:
// do something with the Tab object of an activated tab
chrome.tabs.onActivated.addListener(function (activeInfo) {
chrome.tabs.get(activeInfo.tabId, function(theTab) {
foo(theTab);
});
});
I'm used to having getters simply return the requested value and just find this interesting. Is this because all these methods (such as getLastFocused here) actually only schedule asynchronous tasks for the browser engine?

I was wondering something similar and came across a good explanation, maybe someone will find this useful as I did:
[The reason for using callbacks in the APIs] has to do with Google Chrome's multi-process architecture. Web pages and JavaScript run in processes which are not only separate from each other, but also from the main browser process which alone has the ability to do things like read & write to the local file system. This is an important security and stability feature for Google Chrome. If calls like this were synchronous, your extension would have to stop everything and wait for the browser process to respond to the request, all the while the user may be trying to interact with the UI of your extension which has become unresponsive. Using asynchronous APIs is more challenging, but it's in the service of the best user experience.
This is from the transcript of this video on the extension API design.

This is a combination of an event handler and some asynchronous actions. In addition, the way scoping works in javascript can be a bit iffy; using closures creates a reliable scope that allows data to be passed about that just couldn't be done in another manner.

From my perspective, one of the reasons, why most methods in the chrome.* APIs are asynchronous, is that extensions usually have to deal with the user interactions. Any asynchronous API in general leads to better application responsiveness. So, developers of the chrome.* APIs simply provide an easier way to write efficient extensions, that will not slow down Google Chrome, making users disappointed.

Related

Are chrome apps code visible to the users?

I was thinking about writing a chrome app in html5. This would be an app on the desktop for the user to use, independent of the internet. However, the concern is what if there are algorithms that I don't want the user to see or copy? I would just want to grant the user the ability to apply it.
Is it impossible to hide the app code that you wouldn't want the user to copy?
No, it's not possible to hide your code. You can obfuscate and minimize it, but that is about it.
If you have proprietary algorithms you're protective of, you can always leave them on a server and use XHR to execute them there. Or you could use native client to have a portion of your app written in C and compiled to a low level intermediate language (portable NaCl, which is preferred), or machine code (NaCl).
Note all native apps have this problem; machine code can also be reverse engineered. Its just easier with HTML / javascript.

Is Google's Webspeech server request-limiting me, and is there a fix?

I've been writing an extension that allows the user to issue voice commands to control their browser, and things were going great until I hit a catastrophic problem. It goes like this:
The speech recognition object is in continuous mode, and whenever the onerror: 'no-speech' or onend events fire, it restarts. This way, the extension is constantly waiting to accept input and reacts whenever a command is issued, even after 5 minutes of silence.
After a few days of of development, today I reached the point where I was testing it in practical use, and I found that after a little while (and with no change to anything on my part), my onend event started firing constantly. As in, looking at the console, I would see 18,000 requests being made in the space of three seconds, all being instantly denied, thus triggering onend and restarting the request.
I'm aware that it would be optimal to wait for sound before sending a request, or to have local speech recognition capabilities without the need for a remote server, but the present API does not allow that.
Are my suspicions correct? Am I getting request limited?
Are my suspicions correct? Am I getting request limited?
Yes
I'm aware that it would be optimal to wait for sound before sending a request, or to have local speech recognition capabilities without the need for a remote server, but the present API does not allow that.
To hide the IP source of your request you can use anonymizer networks like Tor, though it will not be fast.
It's naive to assume Google will spend resources to process all audio being recorded on your system. In your application development it is better to rely on API which provides at least some guarantees. It could be either commercial API or open source implementation like CMUSphinx.
With CMUSphinx, you can also properly implement command keyword detection and increase accuracy by specifying the grammar of the commands.
You could also use a Voice Activity Detection (VAD) algorithm to detect when a user is talking. This can be done by either setting a volume threshold or a frequency threshold (Human speech is usually less than 400hz for example). This way, you won't send useless requests to Google unless those conditions are meant. I would not recommend using Tor as this would significantly increase latency. CMUSphinx is probably the best local system option, but if still want to use a web-based service, I would recommend either using a Voice Activity Detection algorithm or finding a different web-based software.

Realtime API for model synchronization

I am looking to extend an existing JavaScript/CoffeeScript application using the realtime API. What I want to do is synchronize a map used by the Model of my application, part of an MVC framework spinejs. This would require that all the operations of the API will be done on the Model of my application (which is pure client-side), and have no direct interaction with the View.
All the open-source examples of realtime-api I have found had the JS code within the HTML being displayed, or much of the operations for authorization/loading etc (quickstart,realtime-cube,realtime-playground).
Is it possible to use realtime-api, without having direct
interaction with the displayed content?
Furthermore, if any examples are available it would be greatly appreciated.
Once the auth is done, all the operations can be performed, without any user operation being necessary (i.e. they don't have to be triggered by a user event).
I can show you our RT code here, although it's non-trivial, the listeners are listening to our own model, which cause RT functions to be invoked.
In terms of the auth, it works fine, except if you want to support multiple accounts. For single accounts you can use the immediate mode to enable signing in without causing a popup.
If there are multiple accounts logged in, you will need a user event to start the auth without having a popup, immediate mode messes up multiple account handling. Note there is a bug in the multiple account selection screen anyway, which causes a poor user experience.

Using WebGL from inside a Web Worker: is it possible ? How?

I opened this matrix multiplication benchmarks and my browser (Firefox 7.0.1) froze until the benchmarks finished (I opened the page in an old Asus EeePC 1000H).
I heard that web workers were invented to separate processing from displaying the web pages. Is it possible to make use of the Web Workers API to make WebGL not stall the whole web browser ?
For the sake of clarity: the benchmark that you linked to does not use WebGL at all. (I should know, I wrote it.) And in the case of that particular benchmark you absolutely could run it in a Web Worker now and it would be perfectly fine.
(Fun fact - Web Workers didn't support TypedArrays when the benchmark was built, and since most of the matrix libraries rely on that it was impractical to run it in a Worker at that time. That has since been fixed.)
Anyway, to answer your original question: No, WebGL cannot run in a worker. The core blocker to this is that in order to get a WebGL context you need to call getContext on a canvas element. Web Workers explicitly disallow DOM access (which is a good thing, BTW!) and as such you'll never be able to access WebGL from a worker.
But that's not as bad as you might think. For one, consider that most all 3D rendering is actually happening in a different thread anyway. Specifically, a whole bunch of threads running on your GPU. The only part the browser has in it is to tell your graphics driver "Hey! Start rendering some triangles using this data!" and then it moves on without waiting for the triangles to actually be rendered. As such, while the draw commands must be executed from the main process, the time it spends blocking that process is (usually) very little.
Of course, that's not what's going to eat up a bunch of your time if you were coding a realtime game. You've got animations, physics, AI, collision detection, pathfinding... there's a lot of non-graphical tasks involved that will eat your CPU alive if you let them. In some case (animation), it's usually just gobs and gobs of matrix math, just like the benchmark you linked to! Fortunately for us, however, that type of processing CAN be done in a Worker, and all we need to communicate back to the main thread is the data required to render the scene.
Yes, this introduces some challenges in terms of synchronization and data transfer, but on the whole it will be vastly preferable to locking up your browser while we try and simulate those 500 boxes colliding.
Yes, on Firefox!
https://hacks.mozilla.org/2016/01/webgl-off-the-main-thread/
We’re happy to announce WebGL in Web Workers in Firefox 44+! Using the new OffscreenCanvas API you can now create a WebGL context off of the main thread.
By default you can't use WebGL in a Web Worker as Toji explained.
You can check out WebGLWorker which is a library that lets you do WebGL stuff in a Web Worker, by transparently proxying commands to the main thread.
Here is a nice blog post that explains how it works.

how to dynamically update HTML5 canvas via server push without page reload?

What I would like to do is create a canvas that will show a network map. It's not really a network map but in terms of explaining it the network map example works best to not bog you down with details that don't pertain to my question.
On the network map I want to display routes the traffic takes. These routes change in time, sometimes as frequently as multiple times per minute. On the server side I have a log file to which each route change is appended as it happens.
I know how to create the canvas, I know how to draw my routes onto the canvas.
Is it possible to have the server push an update to the canvas without requiring a page reload/refresh, essentially requiring no user interaction at all? The routes drawn just automagically change?
This would need to work on IIS so a jscript or .Net based solution would be necessary. I won't be able to install PHP, Python, Ruby etc.
Thanks in advance for any insights you can provide.
I recommend that you look at a WebSockets solution to push the information from the server to the client (JavaScript). When you receive the update you can update the canvas as required.
Technologies you should look at if your preferred server technology is .NET would be a service like Pusher, who I work for, and our .NET APIs which let you push updates to the client via our REST API.
If you would prefer to host your own realtime infrastructure then you could look at WebSync (which is actually a Comet technology) which integrates with IIS and also XSockets. There are also a number of realtime technologies on this guide which may interest you. If you've any further questions just let me know.
Server-Sent Events: http://www.html5rocks.com/en/tutorials/eventsource/basics
( Server-sent events is a technology for providing push notifications from a server to a browser client in the form of DOM events. The Server-Sent Events EventSource API is now being standardized as part of HTML5[1] by the W3C. )
Yes, I've done this before (with an ajax-based drawing application). It's very possible. Send packets of information via AJAX (JSON or something), interpret them, and draw them on the client's canvas element. This is trivial to design (and easy to implement using something like jQuery). It seems that you already figured out you need to have a server-side script that pushes information to a web page and a web page that actually draws stuff on the canvas. That's essentially all it is.