{"id":21037579,"url":"https://github.com/faranalytics/scalability","last_synced_at":"2025-10-18T05:16:27.058Z","repository":{"id":216569949,"uuid":"740770672","full_name":"faranalytics/scalability","owner":"faranalytics","description":"Scalability is a type-safe service scaling facility built on Network-Services.","archived":false,"fork":false,"pushed_at":"2025-01-18T22:52:49.000Z","size":170,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-26T09:04:39.540Z","etag":null,"topics":["multithreading","nodejs","scalable","worker-threads"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/scalability","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/faranalytics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-09T03:00:50.000Z","updated_at":"2025-01-18T22:52:51.000Z","dependencies_parsed_at":"2025-01-18T00:30:49.693Z","dependency_job_id":null,"html_url":"https://github.com/faranalytics/scalability","commit_stats":null,"previous_names":["faranalytics/scalability"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faranalytics%2Fscalability","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faranalytics%2Fscalability/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faranalytics%2Fscalability/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faranalytics%2Fscalability/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/faranalytics","download_url":"https://codeload.github.com/faranalytics/scalability/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248199136,"owners_count":21063641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["multithreading","nodejs","scalable","worker-threads"],"created_at":"2024-11-19T13:26:58.756Z","updated_at":"2025-10-18T05:16:22.006Z","avatar_url":"https://github.com/faranalytics.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# _Scalability_\n\nScalability is a type-safe service scaling facility built on _Network-Services_.\n\n## Introduction\n\n_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.\n\n_Scalability_ allows you to easily transform your single threaded application into a multithreaded one.\n\n### Features\n\n- Call methods on a Service App running in a Worker thread using a type-safe API: _code completion_, _parameter types_, and _return types_.\n- Return values _and_ Errors are marshalled back to the caller.\n- Infinite property nesting; you can use a Service API to call _nested_ properties on a Service App at any depth.\n- 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.\n\n## Table of contents\n\n- [Installation](#installation)\n- [Concepts](#concepts)\n- [Usage](#usage)\n- [API](#api)\n- [Support](#support)\n\n## Installation\n\n```bash\nnpm install scalability\n```\n\n## Concepts\n\n_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).\n\nPlease see the [_Network-Services_](https://github.com/faranalytics/network-services#concepts) documentation if you would like to learn more about these concepts.\n\n## Usage\n\nA _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`.\n\n### Implement the `index.ts` module\n\nThis is the module that runs in the main thread.\n\n#### Import the `createService` and `createWorkerPool` helper functions and the **_type_** of the service application (i.e., `Greeter`) that will run in the Worker thread.\n\n```ts\nimport { once } from \"node:events\";\nimport { createService, createWorkerPool } from \"scalability\";\nimport { Greeter } from \"./service.js\";\n```\n\n#### Create a pool of Workers consisting of 10 instances of the `service.js` module.\n\n```ts\nconst workerPool = createWorkerPool({\n  workerCount: 10,\n  workerURL: \"./dist/service.js\",\n});\n```\n\n#### Wait for the Workers to come online.\n\n```ts\nawait once(workerPool, \"ready\");\n```\n\n#### Create a Service using the `WorkerPool` stream and a Service API of type `Greeter`.\n\nThe `greeter` object will support _code completion_, _parameter types_, and _return types_.\n\n```ts\nconst service = createService(workerPool);\nconst greeter = service.createServiceAPI\u003cGreeter\u003e();\n```\n\n#### Call the `greet` method on the `Greeter` 100 times and log the results.\n\nThe `greeter.greet` method returns a promise because it is called asynchronously using a `MessagePort`.\n\n```ts\nconst results = [];\nfor (let i = 0; i \u003c 100; i++) {\n  results.push(greeter.greet(\"happy\"));\n}\n\nconst result = await Promise.all(results);\nconsole.log(result);\n```\n\n### Implement the `service.ts` module\n\nThis is the scaled module specified in the options of the `WorkerPool` constructor. It contains the `Greeter` Service App.\n\n#### Import the `createPortStream` and `createService` helper functions.\n\n```ts\nimport { createPortStream, createService } from \"scalability\";\n```\n\n#### Implement a `Greeter` service.\n\n```ts\nexport class Greeter {\n  // Create a friendly Greeter Application.\n  greet(kind: string) {\n    for (let now = Date.now(), then = now + 100; now \u003c then; now = Date.now()); // Block for 100 milliseconds.\n    return `Hello, ${kind} world!`;\n  }\n}\n```\n\n#### Create a `PortStream` adapter instance using the `createPortStream` helper function.\n\nThis adapter will wrap the Worker thread's `parentPort` in a `stream.Duplex` in order for it be used by _Network-Services_.\n\n```ts\nconst portStream = createPortStream();\n```\n\n#### Create a Service using the portStream instance and create a Service App using an instance of `Greeter`.\n\n```ts\nconst service = createService(portStream);\nservice.createServiceApp(new Greeter());\n```\n\nThat'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.\n\n## API\n\n### The ScalableService class\n\n#### scalability.createService(stream)\n\n- `stream` `\u003cWorkerPool | PortStream\u003e` 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`.\n\nReturns: `\u003cService\u003e`\n\n_public_ **service.createServiceApp\\\u003cT\\\u003e(app, options)**\n\n- `app` `\u003cobject\u003e` An instance of your application.\n- `options` `\u003cServiceAppOptions\u003cT\u003e\u003e`\n  - `paths` `\u003cArray\u003cPropPath\u003cAsync\u003cT\u003e\u003e\u003e\u003e` 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`.\n\nReturns: `\u003cServiceApp\u003cT\u003e\u003e`\n\n_public_ **service.createServiceAPI\\\u003cT\\\u003e(options)**\n\n- `options` `\u003cServiceAPIOptions\u003e`\n  - `timeout` `\u003cnumber\u003e` Optional argument in milliseconds that specifies the `timeout` for function calls. **Default:** `undefined` (i.e., no timeout).\n\nReturns: `\u003cAsync\u003cT\u003e\u003e` A `Proxy` of type `\u003cT\u003e` that consists of asynchronous analogues of methods in `\u003cT\u003e`.\n\n### The WorkerPool class\n\n#### scalability.createWorkerPool(options)\n\n- `options` `\u003cWorkerPoolOptions\u003e`\n  - `workerCount` `\u003cnumber\u003e` Optional argument that specifies the number of worker threads to be spawned.\n  - `workerURL` `\u003cstring | URL\u003e` The URL or path to the `.js` module file. This is the module that will be scaled according to the value specified for `workerCount`.\n  - `restartWorkerOnError` `\u003cboolean\u003e` A boolean setting specifying if Workers should be restarted on `error`. **Default**: `false`\n  - `workerOptions` `\u003cworker_threads.WorkerOptions\u003e` Optional `worker_threads.WorkerOptions` to be passed to each Worker instance.\n  - `duplexOptions` `\u003cstream.DuplexOptions\u003e` Optional `stream.DuplexOptions` to be passed to the `stream.Duplex` i.e., the parent class of the `WorkerPool`.\n\nReturns: `\u003cWorkerPool\u003e`\n\nA `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.\n\n### The PortStream class\n\n#### scalability.createPortStream(options)\n\n- `options` `\u003cstream.DuplexOptions\u003e` Optional `stream.DuplexOptions` to be passed to the `stream.Duplex` i.e., the parent class of the `PortStream`.\n\nA `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.\n\n## Support\n\nIf 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.\n\n- [Adam Patterson](https://github.com/adamjpatterson)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaranalytics%2Fscalability","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffaranalytics%2Fscalability","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaranalytics%2Fscalability/lists"}