Hamsters.js attempts to mimic exactly how you would normally make functions in JavaScript in order to make threading your functions feel as natural as possible to your everyday work flow. The library is traditionally invoked by calling a function named hamsters.run
this function takes several arguments that are paramount to making multi-threading easy on you. These arguments are described below and will be important to understand moving forward.
The first to understand is that Hamsters.js is a message passing interface at its core, thus when invoking functions with the library we need to instruct the library how to operate by passing a params object (message) to the library.
var params = {
foo: 'bar'
};
hamsters.run(params,....);
The next argument we'll use is going to be the logic we want executed inside a thread or thread(s), the params object we passed before will be accessible within the context of our function. You should now be able to see how to ensure different things like variables and functions can be accessed within your threads.
hamsters.run(params, function() {
const myVar = params.foo;
});
The third and final argument is going to be our onSuccess callback method, the only argument required for this function is your output.
hamsters.run(params, function() {
const myVar = params.foo;
}, function(results) {
console.log(results);
});
Back to the original params object, there are some conventions to follow in order to get the best performance and reliability out of the library. Hamsters.js was built with the goal of parallelism and not concurrency, though the library does both very well the primary goal was parallel execution. Due to this various design decisions were made to assist in that aim, one of those decisions is how the library splits data between threads for execution, therefore any array that you want accessed within more than one thread must have the index of array within your params object.
const params = {
array: [1, 2, 3, 4]
};
hamsters.run(params, function() {
for(var i = 0; i < params.array.length; i++) {
rtn.data.push(params.array[i] * 4);
}
}, function(results) {
console.info(results);
});
Using this convention makes it extremely simple to parallelize the method above by simply changing one option in your params object. Using the method below now 4 threads will complete the same task with each thread only operating on a single digit of the array.
var params = {
array: [1, 2, 3, 4],
threads: 4
};
hamsters.run(params, function() {
for(var i = 0; i < params.array.length; i++) {
rtn.data.push(params.array[i] * 4);
}
}, function(results) {
console.info(results);
});
Hopefully now you can start to see the power the library gives you. Taking things a step further the library uses an internal return object called rtn, this rtn object is paramount for the library to have a consistent way to handle thread outputs. Thus when we want to return a value from a thread we need to push our results into the rtn.data array. Alternatively you can make rtn.data your output but only if your output is already an array.
hamsters.run(params, function() {
rtn.data.push(params.foo);
}, function(results) {
console.log(results); // 'foo';
});
Now that you see how to make use of the library let's breakdown the available library options for execution.
var params = {
array: Array,
threads: Integer,
mixedOutput: Boolean,
dataType: String,
sort: String,
indexes: Object
};
threads - This optional argument will tell the library how many threads to execute the function declared previously across, this allows on a very easy level to change how many threads you are executing across. If you do not supply a value here the library defaults to a value of 1
.
mixedOutput - This optional argument will allow you to have an output with a different size than your input. If you do not supply a value here the library defaults to false
.
indexes - This optional argument will tell the library which pieces of data contained within the params.array each thread will operate on, by default the Hamsters.js will automatically split data evenly amongsts all threads for parallel processing however using this advanced option you can have thread 0 operate on all data between starting index 0 and ending index 500, while having thread 1 operate on all data starting between index 501 and ending index 510, controlling how much data each thread works with to get the best possible performance out of a given platform. [{start: 0, end: 500}, {start: 501, end: 510}]
.
dataType - This optional argument will inform the library that our data array is one of JavaScript's Typed Arrays, when making use of this argument the library will automatically format your output to match the specified dataType
.
sort - This optional argument will tell the library to automatically sort our final output either alphabetically or numerically, this argument has a default value of null
and can be configured using the sorting options.
Anything else included in the params object will be accessible within the execution context of a thread or multiple threads depending on how you use the library.