Neatly Packaged Modules

    multiworker

    1.0.3 • Public • Published

    Summary

    MultiWorker is a wrapper around node's and the browser's native (web) worker API. Features include:

    • Post data to workers and use callbacks to handle results.
    • Queue processes across multiple worker threads.
    • Build workers from functions, instead of needing a separate JS file.

    Installation

    Install via NPM:

    npm install --save multiworker

    Then use in your script:

    import MultiWorker from 'multiworker';

    Or, include the script the old fashioned way to make the MultiWorker constructor available globally:

    <script src="dist/multiworker.min.js"></script>

    Usage

    Basic usage

    A MultiWorker instance is created with a function which is used as the code for the worker.

    var worker = new MultiWorker(function () {
      self.receive = function (n) {
        self.return(n + 1);
      }
    });

    In order to interact with the worker, we use the post method. This triggers the self.receive function inside the worker, which returns a value with self.return.

    worker.post(5, function (n) {
      console.log(n); // => 6
    });

    Both worker.post() in the main thread and self.return() and self.post() in the worker can receive an array of transfers as last argument, to support Transferables.

    var worker = new MultiWorker(function () {
      self.receive = function (inputBuffer) {
        // Worker now has ownership of the input buffer
        var resultBuffer = inputBuffer
        self.return(resultBuffer, [resultBuffer]);
        // Ownership of the result buffer has been transferred to the main thread
      }
    });
    var inputBuffer = new ArrayBuffer(5);
    worker.post(inputBuffer, function(resultBuffer) {
      // Main thread now has ownership of the result buffer
    }, [inputBuffer]);
    // Ownership of the input buffer has been transferred to the worker

    Options

    worker

    When creating a MultiWorker instance, a function can be passed:

    var worker = new MultiWorker(function () {
      self.receive = self.return; // Simply return the input
    });

    Alternatively, a filepath, URL, or a stringified IIFE can be used.

    var worker = new MultiWorker('workers/example.js');
    
    worker.post('foo', function () {
      // This post won't occur until example.js has been fetched and the worker ready.
    });

    The worker can also be defined in an options object:

    var worker = new MultiWorker({
      worker: function () {
        self.receive = self.return; // Simply return the input
      }
    });

    The worker url can also be passed as first argument, and all other options in an object literal as second argument:

    var worker = new MultiWorker('workers/example.js', { threads: 2 })

    callback

    A function to be called whenever a worker sends a value back to the main program via self.post or self.return.

    var worker = new MultiWorker({
      worker:   function () {
        self.receive = self.return; // Simply return the input
      },
      callback: function (val) {
        console.log(val);
      }
    });
    
    worker.post(1); // The callback function above will log 1 in the console

    If a callback is passed as an argument when the post request is made, then the default callback is not used.

    var worker = new MultiWorker({
      worker:   function () {
        self.receive = self.return; // Simply return the input
      },
      callback: function (val) {
        console.log(val);
      }
    });
    
    worker.post(1, function (val) {
      alert(val); // The callback function above will not be used. 1 will be alerted.
    });

    threads

    The number of workers to spawn. The default is 1.

    Multiple web workers:

    var worker = new MultiWorker({
      worker:  function () {
        self.receive = self.return; // Simply return the input
      },
      threads: 2
    });
    
    // The posts below are processed in parallel.
    // There is a chance that the second post will return first.
    worker
      .post(42)
      .post(11);

    A single web worker:

    var worker = new MultiWorker({
      worker:  function () {
        self.receive = self.return; // Simply return the input
      },
      threads: 1
    });
    
    // The posts below are processed in series.
    worker
      .post(42)
      .post(11);

    dependencies

    An array of named functions that can be used globally in the workers. These functions must be named and not make references to data outside the function scope.

    var worker = new MultiWorker({
      worker: function () {
        self.receive = function (n1, n2) {
            self.return(multiply(n1, n2) + add(n1, n2));
        }
      },
        dependencies: [
          function multiply(n1, n2) {
            return n1 * n2;
          },
          function add(n1, n2) {
            return n1 + n2;
          }
      ]
    });
    
    worker.post(10, 2, function (n) {
      console.log(n); // => 32
    });

    MultiWorker Methods

    post([...args], [callback], [transfers])

    Interact with a MultiWorker instance. This method accepts an arbitrary number of parameters, which the worker can access with the self.receive method.

    A callback can be passed - this is used instead of any default callback that may have been defined when creating the worker instance.

    var worker = new MultiWorker(function () {
      self.receive = function (n1, n2) {
        self.return(n1 + n2);
      }
    });
    
    worker.post(2, 2, function (result) {
      console.log(result); // => 4
    });

    terminate([callback | instant])

    Terminates the MultiWorker instance. The instance can no longer be used once this method has been called.

    // Wait for post to return, then terminate
    worker.post(10).terminate();
    // Wait for post to return, then terminate and run the callback
    worker.post(10).terminate(function () {
      console.log('Worker terminated');
    });
    // Terminate instantly, without waiting for result from any pending posts
    worker.post(10).terminate(true);

    Worker Methods

    A few methods are made available inside the workers. These are attached to the self object.

    self.receive([...args])

    Fired in response to calling post() on a MultiWorker instance. This is the start of any process from within a worker.

    var worker = new MultiWorker(function () {
      self.receive = function (n1, n2) {
        self.return(n1 + n2);
      }
    });
    
    worker.post(2, 2, function (result) {
      console.log(result); // => 4
    });

    self.return([...args], [transfers])

    Sends a response back to the main thread. This will be called inside of self.receive - see the code example for that method for usage.

    self.post([...args], [transfers])

    Similar to self.return, but will not mark the current task as finished. self.return must be called after all work is done in order to start processing the next item in the queue.

    var worker = new MultiWorker({
      worker:   function () {
        self.receive = function () {
          var i = 100;
    
          // A pointless loop to demonstrate.
          // A real-world usage could be a progress bar.
          while (i--) {
            if (i) {
              self.post(i);
            } else {
              self.return(i);
            }
          }
        }
      },
      callback: function (n) {
        if (!this.done) {
          console.log('left to complete: ' + n);
        } else {
          console.log('Finished');
        }
      }
    });
    
    
    worker
      .post()
      .post(); // This second post won't execute until self.return is called in response to the previous post.

    Developing

    To continuously run the tests while editing, run

    npm start
    

    and open your browser on http://localhost:3000.

    To build the standalone version, run

    npm run build
    

    To ensure correct code style and that the library runs both in node and browsers, run

    npm test
    

    License

    This project is licensed under the ISC License - see the LICENSE.md file for details

    Install

    npm i multiworker

    DownloadsWeekly Downloads

    8

    Version

    1.0.3

    License

    ISC

    Unpacked Size

    135 kB

    Total Files

    21

    Last publish

    Collaborators

    • ahocevar
    • dlevs