Multithreaded Aurelia app

Hi guys. I’ve written a small application that searches for optimal golomb rulers in Aurelia. It is multithreaded (uses web workers) which is what I wanted to try. Check it out if you like: OGR.JS

You can also read more about it on by blog.

I used the Aurelia CLI + webpack + worker-loader(npm) to be able to work with the web workers in a somewhat modern way, but it would be really nice if web workers could be integrated with Aurelia in an even better way.

2 Likes

How would you want Web Workers better integrated?

Part of the problem is that Web Workers have a completely different context and all data passing between the worker and front end has to be serialised. Firstly, the implementation is going to have to be different for each module loader.

For example, with systemjs I have created the below worker.js does much the same as the worker-loader that you’re using with webpack. The one below is pretty simple and can only call static methods on classes in the Web Worker context.

importScripts('jspm_packages/system.js', 'config.js');
onmessage = function (event) {
  var data = event.data;
  System.import(data.library)
    .then(function (lib) {
      var library = lib[event.data.type];
      var method, obj;

      // get static method
      method = library[event.data.method];

      var output = method.apply(obj, event.data.args);
      event.data.result = output;
      self.postMessage(event.data);
    })
    .catch(function (error) {
      console.error(error)
    });
};

For this to work, I have to pass the following data to it via postMessage:

{
  // name of library or path to file that I want loaded
  library: './utils/background-compression',
  // The export to use from the module
  type: 'BackgroundCompression',
  // the static method to call on the class
  method: 'decompress',
  // arguments to pass to the above method
  args: ['arguments' , 'to-pass-to', 'method']
}

There are certainly libraries that make this proxying easier and will promisify the result for you, but the serialisation between the front end and the worker means that sharing class instances between the two has a lot of issues.

I prefer (require?) TypeScript, but I’m pretty new to it. But something like this would be nice, where all the worker-related stuff would be handled by the “AureliaWebWorker” class:

abstract class AureliaWebWorker {
    abstract OnMessage(message: any): void;    
}

class SomeWork extends AureliaWebWorker {
    // Constructor with dependency injection support
    constructor(private progress: (message: any) => void) {
        super();
    }

    OnMessage(message: any) : void {
        // do something here and optionally send progress messages back 
    }
}

This interests me too. Recently I tried PWA with ASP.NET Core 2.0, things looked quite smooth with the available dotnet templates and Nuget packages. I’ll just provide the issue here since it outlines the packages and the problem in case someone is interested (and not to upgrade to WebPack 4.0 just yet): https://github.com/aspnet/JavaScriptServices/issues/1499.