subservient
TypeScript icon, indicating that this package has built-in type declarations

1.0.7 • Public • Published

Subservient

Multithreading can be easy

» Getting Started

» Install

Install with npm:

npm install subservient

Install with yarn

yarn add subservient

» Basic Example

index.js:

import { createFarm } from 'subservient';
 
// Create a worker farm
const farm = createFarm('worker.js', {
    maxSize: 2, // Maximum amount of workers
});
 
(async () => {
    const res = await (await farm.spawn()).hardTask();
    console.log(`Thread returned: ${res}`);
    await farm.end();
})();
 

worker.js

import { expose } from 'subservient';
 
expose({
    hardTask() {
        return new Promise((resolve) => {
            setTimeout(() => resolve('Done!'), 3000);
        });
    }
});

Output:

Worker returned: Done!

» Farms

When a task is called, a Farm looks for an idle worker. If none is found, it creates a new one. After the task is done, it will idle for some time and terminate if no new tasks is received within that time.

createFarm(file: PathLike, options: FarmOptions): WorkerFarm

Create a new worker farm.

Arguments:

  • file Path to the worker module
  • options Self-explanatory
    • maxSize Max amount of workers in a farm (default: 3)
    • idleTime Amount of milliseconds that a worker can idle before terminating (default: 5000)

WorkerFarm.spawn(): Promise<Worker>

Find an idle worker. If none exists, create one.

Running a task

A worker has every method exposed by its corresponding worker module. In the example, expose call in worker.js exposes a function called hardTask. Calling that function on the worker returns a Promise which resolves when the corresponding worker function returns. If the worker function returns a Promise, that promise is awaited before resolving.

» Pools

When a pool is created, it will start size amount of parallel threads. Each time a task is sent to the pool, a free thread is chosen and the task is passed to that thread. A pool cannot dynamically create more threads.

index.js

import { createPool } from 'subservient';
 
// Create a worker pool with 3 workers
const pool = createPool('worker.js', 3);
 
(async () => {
    const res = await (await pool.spawn()).hardTask();
    console.log(`Thread returned: ${res}`);
    await pool.end();
})();

worker.js (Same as in the first example):

import { expose } from 'subservient';
 
expose({
    hardTask() {
        return new Promise((resolve) => {
            setTimeout(() => resolve('Done!'), 3000);
        });
    }
});

This does the same thing as in the farm example, but in a slightly different manner.

The Pool API is the same as the Farm API.

» Worker Farms vs. Pools

Subservient provides two different types of worker groups: Farms and Pools. A Pool always has a fixed amount of workers, ready to take tasks. A Farm creates new workers as they are needed and destroys them after a fixed amount of idle time.

Starting a task in a Farm takes longer because the worker must first be created, but is also more efficient than a pool because there aren't any unused workers lingering around, occupying resources.

So, use what suits you best. For Example, a server that needs to serve quickly to many users should use a pool because of its smaller delay when starting tasks. On the contrary, a very resource-heavy program should use a farm to save resources when idle.

Package Sidebar

Install

npm i subservient

Weekly Downloads

8

Version

1.0.7

License

GPL-3.0

Unpacked Size

104 kB

Total Files

39

Last publish

Collaborators

  • codemaster138