DOMWorkerThreads: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
No edit summary
Line 5: Line 5:
This is an API '''proposal''' for DOM Worker Threads.
This is an API '''proposal''' for DOM Worker Threads.


At this time this document is not complete and is not yet ready for general consideration or debate. It's just getting started!
At this time this document is not complete.  While we invite discussion on this topic, this is not a stable API proposal, and Mozilla won't implement anything based on it till it becomes stable.


Look for a post to mozilla.dev.platform when this proposal is ready to be discussed.
Look for a post to mozilla.dev.platform when this proposal is ready to be discussed.

Revision as of 18:56, 26 June 2008

DOM Worker Threads API Proposal

Abstract

This is an API proposal for DOM Worker Threads.

At this time this document is not complete. While we invite discussion on this topic, this is not a stable API proposal, and Mozilla won't implement anything based on it till it becomes stable.

Look for a post to mozilla.dev.platform when this proposal is ready to be discussed.

Introduction

Use Cases

Terminology

A worker is an execution context for JavaScript that runs off of the main UI thread. The global scope for a worker is almost empty - familiar objects such as window and document are not available, nor is the Mozilla-specific Components object.

A worker pool is a collection of related workers. Workers within a pool can communicate with each other freely, but workers cannot communicate with workers from another pool.

Conformance

Dependencies

Specification Proposal

#include "nsISupports.idl"

interface nsIDOMWorkerThread;
interface nsIScriptError;

[scriptable, function, uuid(e50ca05d-1381-4abb-a021-02eb720cfc38)]
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)]
interface nsIDOMWorkerErrorListener : nsISupports
{
  /**
   * 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)]
interface nsIDOMWorkerThread : nsISupports
{
  /**
   * Sends a message to the worker.
   *
   * @param aMessage (in DOMString)
   *        The message to send. This may be a string or an object that can be
   *        serialized via JSON (see http://developer.mozilla.org/en/docs/JSON).
   */
  void postMessage(in DOMString aMessage);
};

[scriptable, uuid(45312e93-8a3e-4493-9bd9-272a6c23a16c)]
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 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;

  /**
   * Create a new worker object by evaluating the given script.
   *
   * @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);

  /**
   * Create a new worker object by evaluating the given script file.
   *
   * @param aSourceScript (in nsIURI)
   *        The script file to compile. See below for details on the scope in
   *        which the script will run. See nsIURI.
   */
  nsIDOMWorkerThread createWorkerFromURI(in DOMString aScriptURI);
};

interface nsIDOMWorkerGlobalScope
{
  /**
   * The worker object that created this scope.
   */
  readonly attribute nsIDOMWorkerThread thisThread;

  /**
   * Sends a message to the pool that created the worker.
   *
   * @param aMessage (in DOMString)
   *        The message to send. This may be a string or an object that can be
   *        serialized via JSON (see http://developer.mozilla.org/en/docs/JSON).
   */
  void postMessageToPool(in DOMString aMessage);

  /**
   * 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;

  /**
   * Loads the scripts indicated from the given URI or array.
   *
   * This function will block until the script files have been loaded and
   * executed. Load order is not guaranteed, but execution order will be
   * determined by the order in the given array.
   *
   * @param aURIString
   *        The URI to load or an array of URIs to load.
   *        XXX We could also make this function take a variable number of
   *            arguments and forget the array...
   *
   * @throws Will throw an nsIException if the URI cannot be loaded or
   *         executed.
   */
  void loadScripts(/* in JSObject aURIStringOrArray */);

  /**
   * Creates a new XMLHttpRequest object.
   *
   * Use: 'var req = new XMLHttpRequest();'
   */
  /* nsIJSXMLHttpRequest XMLHttpRequest(); */

  /**
   * See nsIDOMJSWindow.idl
   */
  void dump(in DOMString str);

  /**
   * See nsIDOMJSWindow.idl
   */
  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 */);
};

The worker pool's scope

The scope for the worker pool is the standard DOM scope. All DOM objects such as window and document are available, as well as functions such as alert() and dump().

The worker's scope

The worker's scope is far more limited. See nsIDOMWorkerGlobalScope above for details.

Sample usage

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <title>Test threads</title>
  <body>
  <script language="javascript">
    var scriptToRun = 'function messageListener(message, source) { ' +
                      '  dump("Worker: " + message + "\\n"); ' +
                      '} ' +
                      'for (var i = 0; i < 10000000; i++) { ' +
                      ' /* do something */ ' +
                      '} '+
                      'postMessageToPool("Done!"); ';

    var wp = navigator.newWorkerPool();
    wp.messageListener = function(message, source) {
      dump("Pool: " + message + "\n");
    };
    wp.errorListener = function(error, source) {
      dump("Pool: error = '" + error + "'\n");
    }

    var threads = []
    for (var i = 0; i < 10; i++) {
      var thread = wp.createWorker(scriptToRun);
      thread.postMessage("hello");
      threads.push(thread);
    }

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

Not In This Specification

References

The only thing I've seen so far is the Google Gears WorkerPool API. We would certainly like to provide a compatibility API that would make migrating Gears code trivial.

Acknowledgements