Gears

WorkerPool

  1. Your HTML file:
    <!DOCTYPE HTML>
    <html><head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Google Gears WorkerPool Demo</title>
    <link rel="stylesheet" type="text/css" href="hello_world_workerpool_files/sample.css">
    <style>
    
    p.results {
      margin: 4px;
    }
    
    </style>
    </head><body onload="init()" id="theBody">
    <h1>Google Gears WorkerPool Demo</h1>
    <div id="view-source">&nbsp;<a href="view-source:http://code.google.com/apis/gears/samples/hello_world_workerpool/hello_world_workerpool.html">View Demo Source</a></div>
    
    <p id="status">
    
    </p><p>
    <table>
    <tbody><tr>
    <td valign="top">Interact with UI:</td>
    <td><input value="Interact" onclick="interact();" type="button">
    </td>
    <td></td>
    </tr>
    <tr>
    <td valign="top">Run expensive computation:</td>
    <td>
        <input id="syncButton" value="Synchronous" onclick="syncComputation();" type="button">
    </td>
    <td><i>Note the synchronous computation blocks UI interaction
           (and may even cause an 'unresponsive script' warning).</i>
    </td>
    </tr>
    <tr>
    <td>
    </td>
    <td>
        <input id="asyncButton" value="Asynchronous" onclick="asyncComputation();" type="button">
    </td>
    <td>
        <i>But you can still interact while the asynchronous computation
           runs in a JavaScript worker.</i>
    </td>
    </tr>
    </tbody></table>
    
    </p><div id="results" style="font-size: 120%;" ;="">
    <p style="font-weight: bold;" class="results">Results
    </p><p class="results" id="message3">Hello, threaded JavaScript.</p><p class="results" id="message4">Parent initialized.</p></div>
    
    <!-- ====================================== -->
    <!-- End HTML code.  Begin JavaScript code. -->
    
    <script src="gears_init.js"></script>
    <script src="sample.js"></script>
    <script src="wpool.js"></script>
    </body><div FirebugVersion="1.3.3" style="display: none;" id="_firebugConsole"></div></html>
    
  2. The wpool.js
    
    function init() {
      insertRow('Hello, threaded JavaScript.');
      parentInit();
    }
    
    function insertRow(message) {
      var results = getElementById('results');
      var id = 'message' + (childNodes(results).length + 1);
      results.innerHTML += '<p class="results" id="' + id + '">';
      setTextContent(getElementById(id), message);
    }
    
    //
    // WorkerPool code
    //
    
    var workerPool = null;
    var childId;
    
    function parentInit() {
      if (!window.google || !google.gears) {
        return;
      }
    
      try {
        workerPool = google.gears.factory.create('beta.workerpool');
      } catch (e) {
        document.getElementById('asyncButton').disabled = true;
        setError('Could not create workerpool: ' + e.message);
        return;
      }
    
      // set the parent's message handler
      workerPool.onmessage = parentHandler;
    
      // create the worker
      try {
       childId = workerPool.createWorkerFromUrl('worker.js');
      } catch (e) {
       setError('Could not create worker: ' + e.message);
      }
    
      // Child workers will always set onmessage before createWorker() returns.
      insertRow('Parent initialized.');
    }
    
    function parentHandler(messageText, sender, message) {
      insertRow('Asynchronous result: ' + message.body);
    }
    
    
    //
    // UI-related functions
    //
    
    var uiToggleState = 0;
    function interact() {
      if (uiToggleState) {
        getElementById('theBody').style.backgroundColor = '#FFFFFF';
        uiToggleState = 0;
      } else {
        getElementById('theBody').style.backgroundColor = '#CCCCCC';
        uiToggleState = 1;
      }
    }
    
    function asyncComputation() {
      if (workerPool) {
        workerPool.sendMessage(112501234, childId);
      }
    }
    
    function syncComputation() {
      var result = identity(112501234);
      insertRow('Synchronous result: ' + result);
    
      function identity(n) {
        var result = 0;
        while (n > 0) {
          result += 1;
          var tempString = 'abc' + '123';  // for slowdown
          n--;
        }
        return result;
      }
    }
    
  3. The worker.js:
    // Copyright 2007, Google Inc.
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions are met:
    //
    //  1. Redistributions of source code must retain the above copyright notice, 
    //     this list of conditions and the following disclaimer.
    //  2. Redistributions in binary form must reproduce the above copyright notice,
    //     this list of conditions and the following disclaimer in the documentation
    //     and/or other materials provided with the distribution.
    //  3. Neither the name of Google Inc. nor the names of its contributors may be
    //     used to endorse or promote products derived from this software without
    //     specific prior written permission.
    //
    // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
    // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
    // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
    // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
    // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
    // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    google.gears.workerPool.onmessage = function(messageText, senderId, message) {
      google.gears.workerPool.sendMessage(identity(message.body), senderId);
    };
    
    function identity(n) {
      var result = 0;
      while (n > 0) {
        result += 1;
        var tempString = 'abc' + '123';  // for slowdown
        n--;
      }
      return result;
    }
    
  4. The sample.js:
    // Copyright 2007, Google Inc.
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions are met:
    //
    //  1. Redistributions of source code must retain the above copyright notice, 
    //     this list of conditions and the following disclaimer.
    //  2. Redistributions in binary form must reproduce the above copyright notice,
    //     this list of conditions and the following disclaimer in the documentation
    //     and/or other materials provided with the distribution.
    //  3. Neither the name of Google Inc. nor the names of its contributors may be
    //     used to endorse or promote products derived from this software without
    //     specific prior written permission.
    //
    // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
    // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
    // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
    // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
    // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
    // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    // On some WinCE devices, IE Mobile uses 'unknown' rather than 'undefined'. If
    // an element has type 'unknown', we can not pass it to a function, so we must
    // pass its type instead.
    function isDefined(type) {
      return (type != 'undefined' && type != 'unknown');
    }
    
    function childNodes(element) {
      if (isDefined(typeof element.childNodes)) {
        return element.childNodes;
      } else if (isDefined(typeof element.children)) {
        return element.children;
      }
    }
    
    function getElementById(element_name) {
      if (isDefined(typeof document.getElementById)) {
        return document.getElementById(element_name);
      } else if(typeof isDefined(document.all)) {
        return document.all[element_name];
      }
    }
    
    function setTextContent(elem, content) {
      if (isDefined(typeof elem.innerText)) {
        elem.innerText = content; 
      } else if (isDefined(typeof elem.textContent)) {
        elem.textContent = content;
      }
    }
    
    function setupSample() {
      // Make sure we have Gears. If not, tell the user.
      if (!window.google || !google.gears) {
        if (confirm("This demo requires Gears to be installed. Install now?")) {
          // Use an absolute URL to allow this to work when run from a local file.
          location.href = "http://code.google.com/apis/gears/install.html";
          return;
        }
      }
    
      var viewSourceElem = getElementById("view-source");
      if (!viewSourceElem) {
        return;
      }
      var elm;
      if (navigator.product == "Gecko") {
        // If we're gecko, we can show the source of the application with the
        // view-source protocol.
        elm = "<a href='view-source:" + location.href + "'>" +
              "View Demo Source" +
              "</a>";
      } else {
        // Otherwise, just tell users how to do it manually.
        elm = "<em>" +
              "To see how this works, use the <strong>view " +
              "source</strong> feature of your browser" +
              "</em>";
      }
      viewSourceElem.innerHTML += elm;
    }
    
    function checkProtocol() {
      if (location.protocol.indexOf('http') != 0) {
        setError('This sample must be hosted on an HTTP server');
        return false;
      } else {
        return true;
      }
    }
    
    function addStatus(message, opt_class) {
      var elm = getElementById('status');
      var id = 'statusEntry' + (childNodes(elm).length + 1);
      if (!elm) return;
      if (opt_class) {
        elm.innerHTML += '<span id="' + id + '" class="' + opt_class + '"></span>';
      } else {
        elm.innerHTML += '<span id="' + id + '"></span>';
      }
      elm.innerHTML += '<br>';
      setTextContent(getElementById(id), message);
    }
    
    function clearStatus() {
      var elm = getElementById('status');
      elm.innerHTML = '';
    }
    
    function setError(s) {
      clearStatus();
      addStatus(s, 'error');
    }
    
    setupSample();
    

José M. Vidal .

12 of 20