UNPKG

@iprokit/service

Version:

Powering distributed systems with simplicity and speed.

225 lines (224 loc) 7.95 kB
/** * @iProKit/Service * Copyright (c) 2019-2025 Rutvik Katuri / iProTechs * SPDX-License-Identifier: Apache-2.0 */ /// <reference types="node" /> import { EventEmitter } from 'events'; import { Mode, Parameters } from './rfi'; import Protocol, { Incoming, Outgoing } from './protocol'; import Coordinator from './coordinator'; declare const pool: unique symbol; /** * `Client` manages connections to an SCP server. * Once connected, it subscribes to receive broadcasts and handles the executions. * * @emits `connect` when the connection is successfully established. * @emits `<operation>` when a broadcast is received. * @emits `pool:create` when a new socket is created and added to the connection pool. * @emits `pool:acquire` when a socket is acquired from the connection pool. * @emits `pool:drain` when all sockets(message) are removed from the connection pool. * @emits `error` when an error occurs. * @emits `close` when all the connections are closed. */ export default class Client extends EventEmitter { #private; /** * Unique identifier of the client. */ readonly identifier: string; /** * Socket connection pool. */ private readonly [pool]; /** * Creates an instance of SCP `Client`. * * @param identifier unique identifier of the client. * @param options options of the client. */ constructor(identifier: string, options?: Options); /** * Remote port of the client. */ get remotePort(): number | null; /** * Remote address of the client. */ get remoteAddress(): string | null; /** * `true` when all sockets in the pool are connected, `false` otherwise. */ get connected(): boolean; /** * Returns the current state of the connection pool. */ get pool(): { size: number; busy: number; idle: number; }; /** * Subscribes to the server to receive broadcasts. */ private subscribe; /** * Process the `Incoming` broadcast stream. * * @emits `<operation>` when a broadcast is received. */ private onBroadcast; /** * Sends a message to the server and returns a promise resolving to a reply. * * @param operation operation pattern. * @param args arguments to send. */ message<Returned>(operation: string, ...args: Array<any>): Promise<Returned>; /** * Sends a message to the server and returns a promise that resolves to `void`, enabling the coordination of signals. * * @param operation operation pattern. * @param coordinator coordinator that coordinates signals. * @param args arguments to send. */ conduct(operation: string, coordinator: Coordinator, ...args: Array<any>): Promise<void>; /** * Creates and returns a new `Incoming` and `Outgoing` stream. * * @param mode mode of the remote function. * @param operation operation of the remote function. * @param parameters optional parameters of the remote function. * @param socket optional socket to use. If not provided, a socket will be acquired from the connection pool. */ IO(mode: Mode, operation: string, parameters?: Parameters, socket?: Socket): Promise<{ outgoing: Outgoing; incoming: Incoming; }>; /** * Returns the least busy and available socket from the connection pool. * * @emits `pool:acquire` when a socket is acquired from the connection pool. */ private acquireSocket; /** * Creates and initializes a new connected socket, then adds it to the connection pool. * * @param options options of the socket. * @param port remote port. * @param host remote host. * @emits `pool:create` when a new socket is created and added to the connection pool. * @emits `pool:drain` when all sockets(message) are removed from the connection pool. * @emits `error` when an error occurs. * @emits `close` when all the connections are closed. */ private createSocket; /** * Initiates a connection to the server. * * @param port remote port. * @param host remote host. * @param callback optional callback added as a one-time listener for the `connect` event. */ connect(port: number, host: string, callback?: () => void): this; /** * Closes all connections to the server. * * @param callback optional callback added as a one-time listener for the `close` event. */ close(callback?: () => void): this; } export interface Options { /** * Maximum number of sockets that can exist in the connection pool. * When the limit is reached, no new sockets will be created. Instead, * existing sockets' I/O queue will be used to handle new messages, * leveraging their FIFO mechanism to ensure proper message ordering. * * @default 10 */ maxPoolSize?: number; /** * Maximum number of messages that a single socket can process before it is closed. * A new socket will be created for further messages. * * @default 100 */ maxMessages?: number; /** * Maximum amount of time (in milliseconds) that a socket can remain idle before it is closed. * The timer resets on activity. If set to `0`, the idle timeout is disabled, * allowing the socket to remain open indefinitely unless explicitly closed. * * @default 0 */ idleTimeout?: number; } /** * Represents a socket connection used by the SCP `Client`. * * @emits `connect` when a connection is successfully established. * @emits `<mode>` when a new incoming stream is received. * @emits `io:drain` when all callbacks in the I/O queue are executed. */ export declare class Socket extends Protocol { #private; /** * Creates an instance of SCP `Socket`. * * @param options options of the socket. */ constructor(options: SocketOptions); /** * `true` when the socket is connected, `false` otherwise. */ get connected(): boolean; /** * Number of I/O streams queued to process. */ get ioQueue(): number; /** * Creates a new `Incoming` and `Outgoing` stream. * * @param mode mode of the remote function. * @param operation operation of the remote function. * @param parameters parameters of the remote function. * @param callback callback executed when the I/O stream is ready. */ createIO(mode: Mode, operation: string, parameters: Parameters, callback: (outgoing: Outgoing, incoming: Incoming) => void): this; /** * Executes one I/O callback at a time in FIFO manner. * Invoked recursively on the `close` event of the current incoming stream. * * @emits `io:drain` when all callbacks in the I/O queue are executed. */ private executeIO; /** * Creates a new `Incoming` stream. * Invoked recursively on the `close` event of the current incoming stream to continuously listen for incoming streams. * * @emits `<mode>` when a new incoming stream is received. */ cycleIncoming(): this; /** * Initiates a connection to the server. * * @param port remote port. * @param host remote host. * @param callback optional callback added as a one-time listener for the `connect` event. */ connect(port: number, host: string, callback?: () => void): this; } export interface SocketOptions { /** * Maximum number of messages this socket can process before it is closed. */ maxMessages: number; /** * Maximum amount of time (in milliseconds) that this socket can remain idle before it is closed. * The timer resets on activity. If set to `0`, the idle timeout is disabled, * allowing the socket to remain open indefinitely unless explicitly closed. */ idleTimeout: number; } export {};