The WorkerPool API allows web applications to run JavaScript code in the background, without blocking the main page's script execution.
In web browsers a single time-intensive operation, such as I/O or heavy computation, can make the UI unresponsive. The WorkerPool API runs operations in the background, without blocking the UI. Scripts executing in the WorkerPool will not trigger the browser's "unresponsive script" dialog.
This API requires user permission. If you would like to customize the default dialog, you can explicitly call google.gears.factory.getPermission()
- see how.
<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript">
// main.js
var workerPool = google.gears.factory.create('beta.workerpool');
workerPool.onmessage = function(a, b, message) {
alert('Received message from worker ' + message.sender + ': \n' + message.body);
};
var childWorkerId = workerPool.createWorkerFromUrl('worker.js');
workerPool.sendMessage(["3..2..", 1, {helloWorld: "Hello world!"}], childWorkerId);
</script>
// worker.js
var wp = google.gears.workerPool;
wp.onmessage = function(a, b, message) {
var reply = message.body[0] + message.body[1] + "... " + message.body[2].helloWorld;
wp.sendMessage(reply, message.sender);
}
The WorkerPool behaves like a collection of processes, rather than threads. Workers do not share any execution state. Changing a variable in one worker has no effect in any other worker. And created workers do not automatically inherit script code from their parents.
Members of a WorkerPool interact with each other only by sending message objects.
A created worker does not have access to the DOM; objects like
document
and window
exist only on the main page.
This is a consequence of workers not sharing any execution state.
However, workers do have access to all JavaScript built-in functions. Most
Gears methods can also be used, through a global variable that is
automatically defined: google.gears.factory
. (One exception is
the LocalServer file submitter, which requires the DOM.) For other
functionality, created workers can ask the main page to carry out requests.
To understand how to use the WorkerPool API, it is useful to look at a typical example.
google.gears.factory
to create a WorkerPool wp
.
wp.onmessage
. It does this before calling
createWorker()
to help ensure no messages will be lost.
wp.createWorkerFromUrl()
with a URL that
returns the full body of script the child will contain.
createWorkerFromUrl()
returns immediately and the parent
continues running.
onmessage
handler,
on the predefined global variable google.gears.workerPool
.
Workers send messages to each other using sendMessage()
.
Any member of a particular WorkerPool can communicate with any other member.
Each sent message triggers the receiver's onmessage
handler.
Message events are handled like all other JavaScript events. In particular,
processing is interleaved the same way: there is an event queue, and the next
event handler is not called until the previous one returns.
The WorkerPool is not a singleton. A page can create multiple WorkerPool instances, and these pools are isolated from each other. This enables multiple gadgets on a page, for example, to use the WorkerPool API without fear of collision.
How does script know which worker ID to send messages to? There are two common ways:
onmessage
, which contains the
sender's worker ID. A "grunt" worker whose purpose is to execute
requests asynchronously will often use this method, blindly
responding to whichever worker made the request.
createWorker()
, which is the ID
of the newly created worker. A worker whose purpose is to coordinate
tasks (usually the application's "main" JavaScript code) will often use
this method. The ID can be sent to, and used by, any member of the
WorkerPool, but this is seldom necessary.
Workers can be loaded across origins using the
createWorkerFromUrl()
method. Workers loaded across origins this
way run in the security context of the origin they are loaded from. This can
be used to allow controlled communication between pages in different origins.
In order for Gears to execute cross-origin workers, the following restrictions must be met:
application/x-gears-worker
.
google.gears.workerPool.allowCrossOrigin()
.
Once allowCrossOrigin()
is called, cross-origin workers
automatically inherit the permissions of the calling origin.
Known Bug: Cross-origin workers do not correctly inherit permissions when the worker URL redirects across origins.
callback onmessage(messageText, senderId, messageObject)
callback onerror(errorObject)
int createWorker(scriptText)
int createWorkerFromUrl(scriptUrl)
void sendMessage(message, destWorkerId)
void allowCrossOrigin()
callback onmessage(messageText, senderId, messageObject) |
|
---|---|
Summary: | Specifies the function to call when this worker receives a message. |
Parameters: |
messageText
- The message contents. (Deprecated. Prefer messageObject.text .)
senderId
- ID of the source worker. (Deprecated. Prefer messageObject.sender .)
messageObject
An object containing all information about the message. Has these properties:
• body - The message content object.
• sender - ID of the source worker.
• origin - The sender's origin, represented as a string of the form: SCHEME://DOMAIN[:PORT].
The port is omitted for standard ports (http port 80, https port 443). • text - The message content string (Deprecated. Prefer message.body instead. If the message sent was a string, this property contains the message. If the message sent was some other type, it will be the empty string.)
|
callback onerror(errorObject) |
|
---|---|
Summary: | Specifies a handler for unhandled errors inside a worker. |
Parameters: |
errorObject
- An object of type "Error" that explains the problem. Has these properties:
• message - Description of the error.
• lineNumber - The line number on which the error occurred.
|
Return value: | Return true to indicate the error was handled, which prevents it from bubbling
up to the parent. |
Details: |
This callback provides functionality in workers similar to the
window.onerror property. If set, it will be
called for any unhandled errors that occur inside a worker.You can use this callback to implement "last-chance" error handling for your workers. For example, you could log all unhandled errors into the Database API. NOTE: This callback can only be set from child workers. |
int createWorker(scriptText) |
|
---|---|
Summary: | Creates a worker from a string of JavaScript code. |
Parameters: |
scriptText
- The entire body of JavaScript code the worker will contain.
|
Return value: | The ID of the created worker. |
Details: |
Gears guarantees the code in scriptText will run
once before any messages are delivered. The code must set an
onmessage handler during that initial execution,
otherwise the worker will never receive messages.
Two global objects are inserted into the namespace of every created worker: • google.gears.factory - Provides a Factory for the worker.• google.gears.workerPool - Gives access to the WorkerPool that created the worker.
Worker IDs are guaranteed to be unique values that are never reused within the same WorkerPool. |
int createWorkerFromUrl(scriptUrl) |
|
---|---|
Summary: | Creates a worker using the JavaScript code fetched from a URL. |
Parameters: |
scriptUrl
- The URL to fetch, which returns the full JavaScript code the worker will contain.A relative URL is resolved using these rules: • When called from a window, use window.location .• When called from a worker, use the worker's base URL. - For workers created by createWorkerFromUrl() , the base URL is the script URL.- For workers created by createWorker() , the base URL is inherited from the creator. |
Return value: | The ID of the created worker. |
Details: |
Known Bug:
createWorkerFromUrl() does not work when called from inside
workers.Gears guarantees the URL will be fetched and the code returned will run once before any messages are delivered. The code must set an onmessage handler during that initial execution,
otherwise the worker will never receive messages.
Two global objects are inserted into the namespace of every created worker: • google.gears.factory - Provides a Factory for the worker.• google.gears.workerPool - Gives access to the WorkerPool that created the worker.
Worker IDs are guaranteed to be unique values that are never reused within the same WorkerPool. Cross-origin workers are allowed. See the overview section for more details. |
void sendMessage(message, destWorkerId) |
|
---|---|
Summary: |
Sends message to the worker specified by destWorkerId .
|
Parameters: |
message
- The message to send. A message can be a boolean, string, number, array,
object, or Blob. Array and object messages can contain booleans, strings,
numbers, nulls, Blobs, or references to other arrays and objects which also
follow these rules.
destWorkerId
- ID of the destination worker.
|
Details: |
Messages sent from worker 1 to worker 2 in a particular order will be received in the same order.
Messages can be sent and received only between members of the same WorkerPool. Messages are copied between workers. Changes to a message received in one worker will not be reflected in the sending worker. |
void allowCrossOrigin() |
|
---|---|
Summary: | A child worker must call this method if it expects to be used across origins. |
Details: |
If a worker was created from a different origin, all methods on
google.gears.factory will fail in that worker until
allowCrossOrigin() is called.
This prevents cross-site scripting attacks where the attacker could load a worker URL from another domain, then send malicious messages to that worker (e.g. "delete-all-data"). Workers that call allowCrossOrigin() should check
messageObject.origin and ignore messages from unexpected
origins.
|