DOMWorkerThreads current: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
No edit summary
 
(6 intermediate revisions by 3 users not shown)
Line 1: Line 1:
== Current API for Firefox 3.1 Alpha 1 ==
This page describes the API used in the Firefox 3.1 Beta 2 release. We expect few changes before final release, and nothing that would break compatibility with what we currently implement.
 
Please do file bugs if you find any!
 
== Sample usage ==
 
fibonacci.html:


<blockquote>
<blockquote>
<code>
<code>
<pre>
<pre>
#include "nsISupports.idl"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <title>Test threads fibonacci</title>
  <body>
 
  <div id="result"></div>
 
  <script language="javascript">
 
    var worker = new Worker("fibonacci.js");
 
    worker.onmessage = function(event) {
      document.getElementById("result").textContent = event.data;
    };
 
    worker.onerror = function(event) {
      dump("Worker error: " + event.data + "\n");
    };
 
    worker.postMessage(10);


interface nsIDOMWorkerThread;
  </script>
interface nsIScriptError;
  </body>
</html>
</pre>
</code>
</blockquote>


[scriptable, function, uuid(e50ca05d-1381-4abb-a021-02eb720cfc38)]
fibonacci.js:
interface nsIDOMWorkerMessageListener : nsISupports
{
  /**
  * An nsIDOMWorkerThread receives the onMessage callback when another
  * worker posts a message to it.
  *
  * @param aMessage (in DOMString)
  *        The message sent from another worker.
  * @param aSource (in nsIDOMWorkerThread)
  *        The worker that sent the message. Useful for a quick response.
  */
  void onMessage(in DOMString aMessage,
                in nsIDOMWorkerThread aSource);
};


[scriptable, function, uuid(9df8422e-25dd-43f4-b9b9-709f9e074647)]
<blockquote>
interface nsIDOMWorkerErrorListener : nsISupports
<code>
{
<pre>
  /**
var results = [];
  * An nsIDOMWorkerPool receives the onError callback when one of its child
  * workers has a parse error or an unhandled exception.
  *
  * @param aMessage (in nsIScriptError)
  *        Details about the error that occurred. See nsIScriptError.
  * @param aSource (in nsIDOMWorkerThread)
  *        The worker that sent the message. Depending on the specific error in
  *        question it may not be possible to use this object (in the case of a
  *        parse error, for instance, aSource will be unusable).
  */
  void onError(in nsIScriptError aError,
              in nsIDOMWorkerThread aSource);
};


[scriptable, uuid(6f19f3ff-2aaa-4504-9b71-dca3c191efed)]
function resultReceiver(event) {
interface nsIDOMWorkerThread : nsISupports
   results.push(parseInt(event.data));
{
  if (results.length == 2) {
   /**
    postMessage(results[0] + results[1]);
  * Sends a message to the worker.
  }
  *
}
  * @param aMessage (in DOMString)
  *        The message to send.
  */
  void postMessage(in DOMString aMessage);
};


[scriptable, uuid(45312e93-8a3e-4493-9bd9-272a6c23a16c)]
onmessage = function(event) {
interface nsIDOMWorkerPool : nsIDOMWorkerThread
   var n = parseInt(event.data);
{
   /**
  * The nsIDOMWorkerMessageListener which handles messages for this pool.
  *
  * Developers should set this attribute to a proper object before another
  * worker begins sending messages to ensure that all messages are received.
  */
  attribute nsIDOMWorkerMessageListener messageListener;


   /**
   if (n == 0 || n == 1) {
  * The nsIDOMWorkerErrorListener which handles errors in child threads.
    postMessage(n);
  *
    return;
  * Developers should set this attribute to a proper object before calling
   }
  * createWorker in order to catch parse errors as well as runtime exceptions.
  */
   attribute nsIDOMWorkerErrorListener errorListener;


   /**
   for (var i = 1; i <= 2; i++) {
  * Create a new worker object by evaluating the given script.
    var worker = new Worker("fibonacci.js");
  *
    worker.onmessage = resultReceiver;
  * @param aSourceScript (in DOMString)
    worker.postMessage(n - i);
  *        The script to compile. See below for details on the scope in which
  }
  *        the script will run.
}
  */
</pre>
  nsIDOMWorkerThread createWorker(in DOMString aScriptText);
</code>
};
</blockquote>


interface nsIDOMWorkerThreadContext
== Full API ==
{
  /**
  * The worker object that created this scope.
  */
  readonly attribute nsIDOMWorkerThread thisThread;
};


interface nsIDOMWorkerGlobalScope
This API shouldn't change between Beta 2 and final with the exception of adding a few properties, so code written to the following spec should continue to work.
{
  /**
  * The thread context.
  */
  readonly attribute nsIDOMWorkerThreadContext threadContext;


  /**
=== The worker object ===
  * The nsIDOMWorkerMessageListener which handles messages for this worker.
  *
  * Developers should set this attribute to a proper object before another
  * worker begins sending messages to ensure that all messages are received.
  */
  attribute nsIDOMWorkerMessageListener messageListener;


  /**
Workers are created as follows:
  * Sends a message to the pool that created the worker.
  *
  * @param aMessage (in DOMString)
  *        The message to send.
  */
  void postMessageToPool(in DOMString aMessage);


  /**
<blockquote>
  * See nsIDOMJSWindow.idl
<code>
  */
<pre>
  void dump(in DOMString str);
var worker = new Worker("workerScript.js");
</pre>
</code>
</blockquote>


  /**
Once created, the worker object has the following interface:
  * See nsIDOMJSWindow.idl
  */
  long setTimeout(/* in JSObject aFunctionOrString, */
                  /* in JSObject aMilisecondDelay, */
                  /* [optional] in aArgsToFunctionOrString */);


<blockquote>
<code>
<pre>
interface Worker : DOMEventTarget
{
   /**
   /**
   * See nsIDOMJSWindow.idl
   * Event listener that will be called whenever a MessageEvent bubbles through
  * the worker with type 'error'. The error message will be stored in the
  * 'data' member of the event.
   */
   */
   long setInterval(/* in JSObject aFunctionOrString, */
   attribute EventListener onerror;
                  /* in JSObject aMilisecondDelay, */
                  /* [optional] in aArgsToFunctionOrString */);


   /**
   /**
   * See nsIDOMJSWindow.idl
   * Event listener that will be called whenever a MesageEvent bubbles through
  * the worker with type 'message'. The message will be stored in the 'data'
  * member of the event.
   */
   */
   void clearTimeout(/* in JSObject aTimeoutId */);
   attribute EventListener onmessage;


   /**
   /**
   * See nsIDOMJSWindow.idl
   * Sends 'aMessage' as the 'data' member of a MessageEvent targeted at the
  * worker's inner scope.
   */
   */
   void clearInterval(/* in JSObject aIntervalId */);
   void postMessage(in DOMString aMessage);
};
};
</pre>
</pre>
</code>
</code>
</blockquote>
</blockquote>


=== The worker pool's scope ===
=== The worker scope ===
 
The scope for the worker pool is the standard DOM scope. All DOM objects such as <code>window</code> and <code>document</code> are available, as well as functions such as <code>alert()</code> and <code>dump()</code>.


=== The worker's scope ===
The global object for the scope in which a worker's script runs has the following interface:
 
The worker's scope is far more limited. See <code>nsIDOMWorkerGlobalScope</code> above for details.
 
== Sample usage ==


<blockquote>
<blockquote>
<code>
<code>
<pre>
<pre>
interface WorkerScope : DOMEventTarget
{
  /**
  * Gets WorkerScope object itself.
  */
  readonly attribute WorkerScope self;


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  /**
<html>
  * Event listener that will be called whenever a MesageEvent bubbles through
  <title>Fibonacci from a worker thread</title>
  * the worker's inner scope with type 'message'. The message will be stored
   <body>
  * in the 'data' member of the event.
  */
   attribute EventListener onmessage;


   <div id="start-div"></div>
   /**
  <p><div id="result-div">Result from worker: (pending)</div></p>
  * Sends 'aMessage' as the 'data' member of a MessageEvent targeted at the
   <div id="end-div"></div>
  * scope's parent worker object.
  */
   void postMessage(in DOMString aMessage);


   <script language="javascript">
   /**
    var startdiv = document.getElementById("start-div");
  * Loads the scripts referenced by the given urls. Begins downloading all
    var resultdiv = document.getElementById("result-div");
  * scripts simultaneously but ensures that they are executed in the order
    var enddiv = document.getElementById("end-div");
  * given.
 
  */
    startdiv.innerHTML = "Started: " + new Date();
  void importScripts([Variadic] in DOMString aURLs);
 
    function scriptToRun(){
      // Hook us up to receive messages from the pool
      this.messageListener = function(message, source) {
        var num = parseInt(message);
        if (isNaN(num)) {
          throw "Pool sent a value we couldn't interpret!";
        }
        postMessageToPool(fibonacci(num));
      };
 
      // Worst implementation of fibonacci *ever*!
      function fibonacci(n) {
        if(n == 0)
          return 0;
        if(n == 1)
          return 1;
        return fibonacci(n - 1) + fibonacci(n - 2);
      }
    }
 
    var wp = navigator.newWorkerPool();
 
    wp.messageListener = function(message, source) {
      resultdiv.innerHTML = "Result from worker: " + message;
      enddiv.innerHTML = "Finished: " + new Date();
    };
 
    wp.errorListener = function(error, source) {
      alert("Worker had an error: " + error);
    }
 
    var thread = wp.createWorker("" + scriptToRun + "scriptToRun();");
    thread.postMessage(35);
 
  </script>
  </body>
</html>


  /**
  * The following constructors are available just as on the main thread:
  *
  * 1. Worker(in DOMString aURL);
  *      var worker = new Worker("scriptUrl.js");
  *
  * 2. XMLHttpRequest();
  *      var xhr = new XMLHttpRequest();
  *
  *    Note: The XHR objects created in a worker script behave identically to
  *          the XHR objects created on the main thread except that the
  *          'responseXML' and 'channel' attributes always return null (see
  *          nsIXMLHttpRequest.idl).
  */


  /**
  * See nsIDOMJSWindow.idl for info on the following methods.
  */
  void dump(in DOMString aMessage);
  long setTimeout();
  long setInterval();
  void clearTimeout();
  void clearInterval();
};
</pre>
</pre>
</code>
</code>
</blockquote>
</blockquote>

Latest revision as of 19:53, 6 November 2008

This page describes the API used in the Firefox 3.1 Beta 2 release. We expect few changes before final release, and nothing that would break compatibility with what we currently implement.

Please do file bugs if you find any!

Sample usage

fibonacci.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <title>Test threads fibonacci</title>
  <body>

  <div id="result"></div>

  <script language="javascript">

    var worker = new Worker("fibonacci.js");

    worker.onmessage = function(event) {
      document.getElementById("result").textContent = event.data;
    };

    worker.onerror = function(event) {
      dump("Worker error: " + event.data + "\n");
    };

    worker.postMessage(10);

  </script>
  </body>
</html>

fibonacci.js:

var results = [];

function resultReceiver(event) {
  results.push(parseInt(event.data));
  if (results.length == 2) {
    postMessage(results[0] + results[1]);
  }
}

onmessage = function(event) {
  var n = parseInt(event.data);

  if (n == 0 || n == 1) {
    postMessage(n);
    return;
  }

  for (var i = 1; i <= 2; i++) {
    var worker = new Worker("fibonacci.js");
    worker.onmessage = resultReceiver;
    worker.postMessage(n - i);
  }
}

Full API

This API shouldn't change between Beta 2 and final with the exception of adding a few properties, so code written to the following spec should continue to work.

The worker object

Workers are created as follows:

var worker = new Worker("workerScript.js");

Once created, the worker object has the following interface:

interface Worker : DOMEventTarget
{
  /**
   * Event listener that will be called whenever a MessageEvent bubbles through
   * the worker with type 'error'. The error message will be stored in the
   * 'data' member of the event.
   */
  attribute EventListener onerror;

  /**
   * Event listener that will be called whenever a MesageEvent bubbles through
   * the worker with type 'message'. The message will be stored in the 'data'
   * member of the event.
   */
  attribute EventListener onmessage;

  /**
   * Sends 'aMessage' as the 'data' member of a MessageEvent targeted at the
   * worker's inner scope.
   */
  void postMessage(in DOMString aMessage);
};

The worker scope

The global object for the scope in which a worker's script runs has the following interface:

interface WorkerScope : DOMEventTarget
{
  /**
   * Gets WorkerScope object itself.
   */
  readonly attribute WorkerScope self;

  /**
   * Event listener that will be called whenever a MesageEvent bubbles through
   * the worker's inner scope with type 'message'. The message will be stored
   * in the 'data' member of the event.
   */
  attribute EventListener onmessage;

  /**
   * Sends 'aMessage' as the 'data' member of a MessageEvent targeted at the
   * scope's parent worker object.
   */
  void postMessage(in DOMString aMessage);

  /**
   * Loads the scripts referenced by the given urls. Begins downloading all
   * scripts simultaneously but ensures that they are executed in the order
   * given.
   */
  void importScripts([Variadic] in DOMString aURLs);

  /**
   * The following constructors are available just as on the main thread:
   *
   * 1. Worker(in DOMString aURL);
   *      var worker = new Worker("scriptUrl.js");
   *
   * 2. XMLHttpRequest();
   *      var xhr = new XMLHttpRequest();
   *
   *    Note: The XHR objects created in a worker script behave identically to
   *          the XHR objects created on the main thread except that the
   *          'responseXML' and 'channel' attributes always return null (see
   *          nsIXMLHttpRequest.idl).
   */

  /**
   * See nsIDOMJSWindow.idl for info on the following methods.
   */
  void dump(in DOMString aMessage);
  long setTimeout();
  long setInterval();
  void clearTimeout();
  void clearInterval();
};