Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Workit is a utility for parallel processing. The approach is that of a thread pool in which a queue of jobs exists and workers pick new jobs as they finish their work. But instead of using threads, we use child processes.
Parallel processing is traditionally difficult code to write, and that's exactly the problem workit aims to solve for you. Workit accomplishes this by providing you with abstractions for easily defining a Worker API you interact with, managing the lifecycle of the worker processes, and managing the distribution of the workload. All you have to do is define a Worker API that you interact with via a Worker Pool.
So how does this thing work? Well - let's think about the setup starting with the worker. A worker is ultimately the child process that processes your data, and you have a couple of ways to define one.
Worker
with methods that process your data. We refer to this as a Worker API.Then you have a worker pool, which is the component you interact with to talk to the workers. A worker pool exposes several methods, but the two important ones for interacting with worker processes are send
and invoke
. You use send
when interacting with a worker function, and you use invoke
when you interact with a Worker API.
The most basic setup is when the pool and the worker are both defined in the same file. This is perhaps an overly simplistic setup, but it is available if you need it.
import Workit from "workit";
if (process.isWorker) {
console.log(process.pid, process.isWorker, "hello world");
}
else {
var workerPool = new Workit.Pool(__filename);
workerPool.stop();
}
index.js
import path from "path";
import Workit from "workit";
var workerPool = new Workit.Pool(path.join(__dirname, "./worker.js"));
workerPool.send("hello world").then(() => {
workerPool.stop();
});
worker.js
export default function(data, done) {
console.log(process.pid, process.isWorker, data);
done();
};
run it
$ node index.js
index.js
import path from "path";
import Workit from "workit";
var workerPool = new Workit.Pool(path.join(__dirname, "./worker.js"));
workerPool.invoke("say", "hello world").then((data) => {
console.log("received", data);
workerPool.stop();
});
worker.js
import Workit from "workit";
class Api extends Workit.Worker {
say(data) {
console.log(process.pid, process.isWorker, data);
return Promise.resolve("done");
}
}
export default Api;
run it
$ node index.js
index.js
import path from "path";
import Workit from "workit";
class Pool extends Workit.Pool {
workerSaid(data) {
console.log(process.pid, process.isWorker, data);
}
}
var workerPool = new Pool(path.join(__dirname, "./worker.js"));
workerPool.invoke("say", "hello world").then(() => {
workerPool.stop();
});
worker.js
import Workit from "workit";
class Api extends Workit.Worker {
say(data, done) {
console.log(process.pid, process.isWorker, data);
this.invoke("workerSaid", "hello back");
done();
}
}
export default Api;
run it
$ node index.js
workit provides you with several different constructs to make parallel processing simple.
Class that manages the queue of jobs and worker processes. You can extend Pool in order to define methods that worker processes can invoke, which allows you to build a two way communication between parent and child processes. You can take a look at the example below for Worker process talking to Process pool
. The constructor takes several arguments:
new Pool(path.join(__dirname, "./worker.js"), { size: 2 }, ["--color"]);
For a list of available options for the child process, please take a look at the nodes child_process.fork documentation.
On top of those options, you can pass in the initial size of the pool by specifying size
as in the example above.
Method to send data to a Worker function.
The call returns a promise that resolves when the worker process is done processing the data.
The example below sends a string to be processed by a worker function.
workerPool.send("Hello world").then(() => console.log("done"));
Method that invokes a method defined in a Worker API.
The call returns a promise that resolves when the worker process is done processing the data.
The example below sends a string to be process by the method say
in a worker api.
workerPool.invoke("say", "Hello world").then(() => console.log("done"));
Method that stops all workers from processing further jobs. All workers will finish processing whatever they are doing before they exit.
workerPool.stop();
Method the rejects all queued jobs that are pending processing. The jobs are rejected with the given error.
workerPool.rejectQueue();
Method that sets the size of the worker pool. The value is absolute, meaning that if you specify 4 then the pool will have a size of 4 worker processes. If the value is smaller than the current, then the pool is reduced to that size gracefully allowing the worker that are going to be removed finish their work. If the value is bigger than the current, then the pool size is increased and jobs are assigned to each worker as needed.
workerPool.size(2);
Array of all the workers. The workers in this array are essentially an adapter for interacting with the underlying worker process. You have several methods available to you that allow you to interact directly with specific worker processes.
Method for sending data to a specific Worker function.
workerPool.workers.forEach((worker) => worker.send("Hello world"));
Method for invoking a method on a specific Worker API method.
workerPool.workers.forEach((worker) => worker.invoke("say", "Hello wold"));
Method to stop a specific worker. This will gracefully let the worker process finish any work in progress before stopping it.
workerPool.workers.forEach((worker) => worker.stop());
Class that allows you to define an API that a worker pool can invoke. All you need to do is extend the Worker class to define your API methods, and export it. Workit will internally manage the lifecycle of your Worker API. The methods exposed by the API get two parameters
done
or the resolved promise, that data will be received by the worker pool for the particular job.Export a simple Worker API with a method say
that a worker pool can invoke.
import Workit form 'workit';
class Worker extends Workit.Worker {
say(data) {
return Promise.resolve("got it");
}
}
export default Worker;
Flag that is true if the code reading the value is executing in a worker process. Otherwise the value is not defined. isWorker
is also available in process.isWorker
.
workit used to be taken up in npm by the now defunct project (https://github.com/shannonmoeller/workit). The author - Shannon - of that project is amazing and let me have the name. Thank you, Shannon!
FAQs
worker pool for managing parallel processing of jobs (tasks)
The npm package workit receives a total of 51 weekly downloads. As such, workit popularity was classified as not popular.
We found that workit demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.