UNPKG

nanolith

Version:

Multi-threading in no time with seamless TypeScript support.

1 lines 1.56 kB
import{randomUUID as v4}from"crypto";import{pool}from"../pool/index.js";import{Service}from"../service/index.js";export class ServiceCluster{#e;#r=new Map;#i=!1;constructor(e,r){this.#i=!!r?.autoRenew,this.#e=e}get activeServices(){return this.#r.size}get currentServices(){return[...this.#r.values()]}get activeServiceCalls(){let e=0;return this.#r.forEach((({service:r})=>e+=r.activeCalls)),e}async launch(e,r={}){if(!e||1===e)return[await this.#s(r)];const i=[];for(let s=1;s<=e;s++)i.push(this.#s(r));return Promise.all(i)}async#s(e={}){if(this.#r.size>=pool.maxConcurrency)return;const r=await this.#e.launchService(e);return this.#t(r),r}addService(e){if(!(e instanceof Service))throw new Error("Can only provide Service instances to .addService().");this.#t(e)}#t(e){const r=v4();this.#r.set(r,{service:e,identifier:r}),e.once("terminated",(async e=>{this.#r.delete(r),this.#i&&0!==e&&await this.launch(1)}))}use(e){if("string"==typeof e&&this.#r.has(e))return this.#r.get(e);if(!this.#r.size)throw new Error("No running services found on this ServiceCluster!");const r=this.#r.values();let i=r.next().value.service;if(1===this.#r.size||0===i.activeCalls)return i;for(const{service:e}of r){if(0===e.activeCalls)return e;i.activeCalls<e.activeCalls||(i=e)}return i}notifyAll(e,r){this.#r.forEach((({service:i})=>{i.sendMessage(e,r)}))}closeAll(){const e=[];return this.#r.forEach((({service:r})=>e.push(r.close()))),Promise.all(e)}closeAllIdle(){const e=[];return this.#r.forEach((({service:r})=>{r.activeCalls<=0&&e.push(r.close())})),Promise.all(e)}}