DOMWorkerThreads current: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
No edit summary
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 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 ==
== Sample usage ==
fibonacci.html:


<blockquote>
<blockquote>
<code>
<code>
<pre>
<pre>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<html>
   <title>Fibonacci from a worker thread</title>
   <title>Test threads fibonacci</title>
   <body>
   <body>


   <div id="start-div"></div>
   <div id="result"></div>
  <p><div id="result-div">Result from worker: (pending)</div></p>
  <div id="end-div"></div>


   <script language="javascript">
   <script language="javascript">
    var startdiv = document.getElementById("start-div");
    var resultdiv = document.getElementById("result-div");
    var enddiv = document.getElementById("end-div");


     startdiv.innerHTML = "Started: " + new Date();
     var worker = new Worker("fibonacci.js");


     function scriptToRun(){
     worker.onmessage = function(event) {
       // Hook us up to receive messages from the pool
       document.getElementById("result").textContent = event.data;
      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*!
     worker.onerror = function(event) {
      function fibonacci(n) {
       dump("Worker error: " + event.data + "\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) {
     worker.postMessage(10);
      alert("Worker had an error: " + error);
    }
 
    var thread = wp.createWorker("" + scriptToRun + "scriptToRun();");
    thread.postMessage(35);


   </script>
   </script>
   </body>
   </body>
</html>
</html>
</pre>
</code>
</blockquote>


fibonacci.js:


<blockquote>
<code>
<pre>
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);
  }
}
</pre>
</pre>
</code>
</code>
</blockquote>
</blockquote>


== Current API for Firefox 3.1 Alpha 2 ==
== Full API ==


This API has *already* changed, so it is only valid for Alpha 2.
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:


<blockquote>
<blockquote>
<code>
<code>
<pre>
<pre>
#include "nsISupports.idl"
var worker = new Worker("workerScript.js");
</pre>
</code>
</blockquote>


interface nsIDOMWorkerThread;
Once created, the worker object has the following interface:
interface nsIScriptError;


[scriptable, function, uuid(e50ca05d-1381-4abb-a021-02eb720cfc38)]
<blockquote>
interface nsIDOMWorkerMessageListener : nsISupports
<code>
<pre>
interface Worker : DOMEventTarget
{
{
   /**
   /**
   * An nsIDOMWorkerThread receives the onMessage callback when another
   * Event listener that will be called whenever a MessageEvent bubbles through
   * worker posts a message to it.
   * the worker with type 'error'. The error message will be stored in the
  *
   * 'data' member of the event.
  * @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,
   attribute EventListener onerror;
                in nsIDOMWorkerThread aSource);
};


[scriptable, function, uuid(9df8422e-25dd-43f4-b9b9-709f9e074647)]
interface nsIDOMWorkerErrorListener : nsISupports
{
   /**
   /**
   * An nsIDOMWorkerPool receives the onError callback when one of its child
   * Event listener that will be called whenever a MesageEvent bubbles through
  * workers has a parse error or an unhandled exception.
   * the worker with type 'message'. The message will be stored in the 'data'
  *
   * member of the event.
  * @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,
   attribute EventListener onmessage;
              in nsIDOMWorkerThread aSource);
};


[scriptable, uuid(6f19f3ff-2aaa-4504-9b71-dca3c191efed)]
interface nsIDOMWorkerThread : nsISupports
{
   /**
   /**
   * Sends a message to the worker.
   * Sends 'aMessage' as the 'data' member of a MessageEvent targeted at the
   *
   * worker's inner scope.
  * @param aMessage (in DOMString)
  *        The message to send.
   */
   */
   void postMessage(in DOMString aMessage);
   void postMessage(in DOMString aMessage);
};
};
</pre>
</code>
</blockquote>


[scriptable, uuid(45312e93-8a3e-4493-9bd9-272a6c23a16c)]
=== The worker scope ===
interface nsIDOMWorkerPool : nsIDOMWorkerThread
{
  /**
  * 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;


  /**
The global object for the scope in which a worker's script runs has the following interface:
  * The nsIDOMWorkerErrorListener which handles errors in child threads.
  *
  * 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;


<blockquote>
<code>
<pre>
interface WorkerScope : DOMEventTarget
{
   /**
   /**
   * Create a new worker object by evaluating the given script.
   * Gets WorkerScope object itself.
  *
  * @param aSourceScript (in DOMString)
  *        The script to compile. See below for details on the scope in which
  *        the script will run.
   */
   */
   nsIDOMWorkerThread createWorker(in DOMString aScriptText);
   readonly attribute WorkerScope self;
};


interface nsIDOMWorkerThreadContext
{
   /**
   /**
   * The worker object that created this scope.
   * 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.
   */
   */
   readonly attribute nsIDOMWorkerThread thisThread;
   attribute EventListener onmessage;
};


interface nsIDOMWorkerGlobalScope
{
   /**
   /**
   * The thread context.
   * Sends 'aMessage' as the 'data' member of a MessageEvent targeted at the
  * scope's parent worker object.
   */
   */
   readonly attribute nsIDOMWorkerThreadContext threadContext;
   void postMessage(in DOMString aMessage);


   /**
   /**
   * The nsIDOMWorkerMessageListener which handles messages for this worker.
   * Loads the scripts referenced by the given urls. Begins downloading all
   *  
   * scripts simultaneously but ensures that they are executed in the order
   * Developers should set this attribute to a proper object before another
   * given.
  * worker begins sending messages to ensure that all messages are received.
   */
   */
   attribute nsIDOMWorkerMessageListener messageListener;
   void importScripts([Variadic] in DOMString aURLs);


   /**
   /**
   * Sends a message to the pool that created the worker.
   * 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();
   *
   *
   * @param aMessage (in DOMString)
   *   Note: The XHR objects created in a worker script behave identically to
   *       The message to send.
  *          the XHR objects created on the main thread except that the
  *          'responseXML' and 'channel' attributes always return null (see
   *         nsIXMLHttpRequest.idl).
   */
   */
  void postMessageToPool(in DOMString aMessage);


   /**
   /**
   * See nsIDOMJSWindow.idl
   * See nsIDOMJSWindow.idl for info on the following methods.
   */
   */
   void dump(in DOMString str);
   void dump(in DOMString aMessage);
 
   long setTimeout();
  /**
   long setInterval();
  * See nsIDOMJSWindow.idl
   void clearTimeout();
  */
   void clearInterval();
   long setTimeout(/* in JSObject aFunctionOrString, */
                  /* in JSObject aMilisecondDelay, */
                  /* [optional] in aArgsToFunctionOrString */);
 
  /**
  * See nsIDOMJSWindow.idl
  */
   long setInterval(/* in JSObject aFunctionOrString, */
                  /* in JSObject aMilisecondDelay, */
                  /* [optional] in aArgsToFunctionOrString */);
 
  /**
  * See nsIDOMJSWindow.idl
  */
   void clearTimeout(/* in JSObject aTimeoutId */);
 
  /**
  * See nsIDOMJSWindow.idl
  */
   void clearInterval(/* in JSObject aIntervalId */);
};
};
</pre>
</pre>
</code>
</code>
</blockquote>
</blockquote>
=== The worker pool's 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 worker's scope is far more limited. See <code>nsIDOMWorkerGlobalScope</code> above for details.

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();
};