Skip to content

Goroutine analogue for Node.js, spreads I/O-bound routine calls to utilize thread pool (worker_threads) using balancer with event loop utilization. 🌱

License

Notifications You must be signed in to change notification settings

metarhia/noroutine

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

cf55a5f Β· Sep 15, 2023

History

33 Commits
Apr 29, 2023
Sep 15, 2023
Sep 15, 2023
Sep 15, 2023
Oct 23, 2021
Jul 2, 2022
Oct 23, 2021
Oct 23, 2021
Jul 3, 2022
Apr 29, 2023
Apr 1, 2022
Jul 3, 2022
Oct 23, 2021
Apr 1, 2022
Sep 15, 2023
Oct 23, 2021
Sep 15, 2023
Sep 15, 2023
Sep 15, 2023
Apr 29, 2023
Oct 23, 2021

Repository files navigation

Node Routine (noroutine)

ci status snyk npm version npm downloads/month npm downloads license

Goroutine analogue for Node.js, spreads I/O-bound routine (tasks) to utilize thread pool with worker_threads using balancer with event loop utilization (see perf_hooks API).

Usage

Install: npm install noroutine

const noroutine = require('noroutine');
const module1 = require('./module1.js');
const module2 = require('./module2.js');
noroutine.init({ modules: [module1, module2] });

(async () => {
  const res1 = await module1.method1('value1');
  const res2 = await module2.method2('value2');
  console.log({ res1, res2 });
})();

Initialization options

noroutine.init({
  modules: [module1, module2],
  pool: 5, // number of workers in thread pool
  wait: 2000, // maximum delay to wait for a free thread
  timeout: 5000, // maximum timeout for executing a functions
  monitoring: 5000, // balancer monitoring interval
  balancerFactory: customBalancerFactory, // balancer factory
});

Balancer Factory

balancerFactory field is optional and serves as a factory for the balancer function. By default, the balancing strategy relies on event loop utilization. However, this default behavior can be extended or modified by specifying a custom balancer factory.

The balancer factory is executed once during the initialization process, and it takes the worker priority pool as a parameter.

The outcome of the balancer factory's execution is the balancer function itself. This function will be executed automatically at regular monitoring intervals, implementing the chosen balancing strategy as defined by the balancer factory.

Example (auto scaling balancer):

noroutine.init({
  modules: [module1, module2],
  pool: 8,
  monitoring: 5000,
  balancerFactory: (pool) => {
    const defaultBalancer = noroutine.defaultBalancerFactory(pool);
    const minCapacity = 1;
    const maxCapacity = pool.getCapacity();
    return () => {
      const currentCapacity = pool.getCapacity();
      let minPriority = Infinity;
      let maxPriority = -Infinity;
      defaultBalancer();
      for (const [, priority] of pool) {
        minPriority = Math.min(minPriority, priority);
        maxPriority = Math.max(maxPriority, priority);
      }
      if (1 / minPriority > 0.9) {
        pool.setCapacity(Math.min(maxCapacity, currentCapacity + 1));
      } else if (1 / maxPriority < 0.1) {
        pool.setCapacity(Math.max(minCapacity, currentCapacity - 1));
      }
    };
  },
});

License & Contributors

Copyright (c) 2021-2022 Metarhia contributors. Noroutine is MIT licensed.
Noroutine is a part of Metarhia technology stack.