https://github.com/faranalytics/scalability
Scalability is a type-safe service scaling facility built on Network-Services.
https://github.com/faranalytics/scalability
multithreading nodejs scalable worker-threads
Last synced: 3 months ago
JSON representation
Scalability is a type-safe service scaling facility built on Network-Services.
- Host: GitHub
- URL: https://github.com/faranalytics/scalability
- Owner: faranalytics
- License: mit
- Created: 2024-01-09T03:00:50.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-01-18T22:52:49.000Z (12 months ago)
- Last Synced: 2025-03-26T09:04:39.540Z (10 months ago)
- Topics: multithreading, nodejs, scalable, worker-threads
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/scalability
- Size: 166 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# _Scalability_
Scalability is a type-safe service scaling facility built on _Network-Services_.
## Introduction
_Scalability_ provides a simple and intuitive API for scaling Node.js modules using Worker threads. You can create a [Service App](https://github.com/faranalytics/network-services#service-app) in your scaled module and call its methods from the main thread using a [Service API](https://github.com/faranalytics/network-services#service-api). Conversely, methods can be called in the main thread from scaled modules in the same way.
_Scalability_ allows you to easily transform your single threaded application into a multithreaded one.
### Features
- Call methods on a Service App running in a Worker thread using a type-safe API: _code completion_, _parameter types_, and _return types_.
- Return values _and_ Errors are marshalled back to the caller.
- Infinite property nesting; you can use a Service API to call _nested_ properties on a Service App at any depth.
- Bi-directional asynchronous RPC - communication goes both ways - _Scalability_ allows for calls from the main thread to a Worker and from a Worker to the main thread.
## Table of contents
- [Installation](#installation)
- [Concepts](#concepts)
- [Usage](#usage)
- [API](#api)
- [Support](#support)
## Installation
```bash
npm install scalability
```
## Concepts
_Scalability_ is an extension of the _Network-Services_ RPC Service facility; hence, the concepts that it introduces are _Network-Services_ concepts e.g., [Services](https://github.com/faranalytics/network-services#service), [Service Apps](https://github.com/faranalytics/network-services#service-app), and [Service APIs](https://github.com/faranalytics/network-services#service-api).
Please see the [_Network-Services_](https://github.com/faranalytics/network-services#concepts) documentation if you would like to learn more about these concepts.
## Usage
A _Scalability_ application consists of a main thread (e.g., `index.js`) and a scaled module (e.g., `service.js`). In this example the module that runs in the main thread is named `index.js` and the module that will be scaled is named `service.js`.
### Implement the `index.ts` module
This is the module that runs in the main thread.
#### Import the `createService` and `createWorkerPool` helper functions and the **_type_** of the service application (i.e., `Greeter`) that will run in the Worker thread.
```ts
import { once } from "node:events";
import { createService, createWorkerPool } from "scalability";
import { Greeter } from "./service.js";
```
#### Create a pool of Workers consisting of 10 instances of the `service.js` module.
```ts
const workerPool = createWorkerPool({
workerCount: 10,
workerURL: "./dist/service.js",
});
```
#### Wait for the Workers to come online.
```ts
await once(workerPool, "ready");
```
#### Create a Service using the `WorkerPool` stream and a Service API of type `Greeter`.
The `greeter` object will support _code completion_, _parameter types_, and _return types_.
```ts
const service = createService(workerPool);
const greeter = service.createServiceAPI();
```
#### Call the `greet` method on the `Greeter` 100 times and log the results.
The `greeter.greet` method returns a promise because it is called asynchronously using a `MessagePort`.
```ts
const results = [];
for (let i = 0; i < 100; i++) {
results.push(greeter.greet("happy"));
}
const result = await Promise.all(results);
console.log(result);
```
### Implement the `service.ts` module
This is the scaled module specified in the options of the `WorkerPool` constructor. It contains the `Greeter` Service App.
#### Import the `createPortStream` and `createService` helper functions.
```ts
import { createPortStream, createService } from "scalability";
```
#### Implement a `Greeter` service.
```ts
export class Greeter {
// Create a friendly Greeter Application.
greet(kind: string) {
for (let now = Date.now(), then = now + 100; now < then; now = Date.now()); // Block for 100 milliseconds.
return `Hello, ${kind} world!`;
}
}
```
#### Create a `PortStream` adapter instance using the `createPortStream` helper function.
This adapter will wrap the Worker thread's `parentPort` in a `stream.Duplex` in order for it be used by _Network-Services_.
```ts
const portStream = createPortStream();
```
#### Create a Service using the portStream instance and create a Service App using an instance of `Greeter`.
```ts
const service = createService(portStream);
service.createServiceApp(new Greeter());
```
That's all it takes to scale this `Greeter` application. Please see the [Hello, World! example](https://github.com/faranalytics/scalability/tree/main/examples/hello_world) for a complete working implementation.
## API
### The ScalableService class
#### scalability.createService(stream)
- `stream` `` An instance of a `WorkerPool` or an instance of a `PortStream`. This is a type narrowed version of the _Network-Services_ `createService` helper function. This helper function will accept either a `WorkerPool` or a `PortStream` as an argument, both of which are `stream.Duplex`.
Returns: ``
_public_ **service.createServiceApp\(app, options)**
- `app` `` An instance of your application.
- `options` `>`
- `paths` `>>>` An `Array` of _property paths_ (i.e., dot-path `string`s). _If defined_, only property paths in this list may be called on the Service App. Each element of the Array is a `PropPath` and a `PropPath` is simply a dot-path `string` representation of a property path. **Default:** `undefined`.
Returns: `>`
_public_ **service.createServiceAPI\(options)**
- `options` ``
- `timeout` `` Optional argument in milliseconds that specifies the `timeout` for function calls. **Default:** `undefined` (i.e., no timeout).
Returns: `>` A `Proxy` of type `` that consists of asynchronous analogues of methods in ``.
### The WorkerPool class
#### scalability.createWorkerPool(options)
- `options` ``
- `workerCount` `` Optional argument that specifies the number of worker threads to be spawned.
- `workerURL` `` The URL or path to the `.js` module file. This is the module that will be scaled according to the value specified for `workerCount`.
- `restartWorkerOnError` `` A boolean setting specifying if Workers should be restarted on `error`. **Default**: `false`
- `workerOptions` `` Optional `worker_threads.WorkerOptions` to be passed to each Worker instance.
- `duplexOptions` `` Optional `stream.DuplexOptions` to be passed to the `stream.Duplex` i.e., the parent class of the `WorkerPool`.
Returns: ``
A `WorkerPool` wraps the `MessagePorts` of the Worker threads into a single `stream.Duplex`. Hence, a `WorkerPool` _is a_ `stream.Duplex`, so it can be passed to the _Network-Services_ `createService` helper function. This is the stream adapter that is used in the module of the main thread.
### The PortStream class
#### scalability.createPortStream(options)
- `options` `` Optional `stream.DuplexOptions` to be passed to the `stream.Duplex` i.e., the parent class of the `PortStream`.
A `PortStream` wraps the `parentPort` of the Worker thread into a `stream.Duplex`. Hence, a `PortStream` _is a_ `stream.Duplex`, so it can be passed to the _Network-Services_ `createService` helper function. This is the stream adapter that is used in the Worker module.
## Support
If you have a feature request or run into any issues, feel free to submit an [issue](https://github.com/faranalytics/scalability/issues) or start a [discussion](https://github.com/faranalytics/scalability/discussions). You’re also welcome to reach out directly to one of the authors.
- [Adam Patterson](https://github.com/adamjpatterson)